Ruby function design and other stuff I like ranting about

Ruby function design and other stuff I like ranting about

Why?

If the posts title looks weird: it is. This is a small rant about code-functionality that makes little to no sense (in my eyes).
This whole article can be summed up like this:

How?

I was talking to a coworker about getting the numerical value of a character, like you can in Java, because a char stores the number behind that character.
As an example of that behavior is this function, that counts the occurrence of every character:

public static int[] countCharacters(String input) {
int[] summand = new int[256];

for (char c : input.toCharArray()) {
summand[c]++;
}
return summand;
}

My naive suggestion was that you could just run number.to_i to convert it to its (what I think is) ASCII number.
The problem with that are cases like converting “49”.to_i, where ruby, as a non-typed language, has to convert that to the number the string represents:

irb(main):017> “12”.to_i
=> 12
irb(main):018> “12”.sum
=> 99

On the one hand there is the “12”.to_i, which translates to 12. Fair enough, that makes sense. The other case, where the String doesn’t represent a number, it just translates to 0:

irb(main):012> “a”.to_i
=> 0
irb(main):013> “fdsgsdf”.to_i
=> 0

That leads to some weird (but expected) behaviour:

irb(main):003> summand = []
=> []
irb(main):006> summand[“a”.to_i] = ‘test’
=> “test”
irb(main):008> summand[“4”.to_i] = ‘test’
=> “test”
irb(main):009> summand
=> [“test”, nil, nil, nil, “test”]

Now look closely at that first codeblock. You might realize that there are two operations used:

irb(main):017> “12”.to_i
=> 12
irb(main):018> “12”.sum
=> 99

The weird part is the “12”.sum – as ruby loves translating strings to the numbers they represent, you would expect that to translate to something like this:

irb(main):018> “12”.sum
=> 12
irb(main):018> “12”.sum
=> 3 # Because 1 + 2 = 3

But you get something completely different:

irb(main):018> “12”.sum
=> 99

And now why does this happen you might as?
Because of this:

irb(main):027> “2”.sum
=> 50
irb(main):028> “1”.sum
=> 49

Because it takes their ASCII representation, the same as java does!

Okay, so shouldn’t this work for accessing arrays?

This (obviously) doesn’t work out of the box, as you need to convert the string to a number:

irb(main):004> summand[“1”] = ‘test’
(irb):4:in `[]=’: no implicit conversion of String into Integer (TypeError)

summand[“1”] = ‘test’
^^^^^^^^^^^^^
from (irb):4:in `

<main>
irb(main):005> summand[“a”] = ‘
test
(irb):5:in `[]=’
: no implicit conversion of String into Integer (TypeError)

summand[“a”] = ‘test’
^^^^^^^^^^^^^
from (irb):5:in `<main>’

What about scientific notation?

“What about scientific notation?” you might ask. That’s also what I was wondering:

irb(main):022> 2e10
=> 20000000000.0
irb(main):024> “2e10”.to_i
=> 2

?!

Yes, you are seeing this right: It converts the “2e10” to a 2, as it’s all the numbers until the first non-number. This behavior is seen in longer strings too:

irb(main):036> “21f10”.to_i
=> 21

Here it cuts the to_i operation after reaching the f.

Actually converting scientific notation to a number

Now, how can we make this work? This is how:

irb(main):037> “2e10”.to_f.to_i
=> 20000000000

And this only works, as numbers of scientific notation have the class Float per default:

irb(main):038> 2e10.class
=> Float

For a dynamically-typed language it still seems to be unable to do a lot of casting for you!

Where is this leading?

Nowhere. Everything I mentioned before is really obscure and won’t be important 99% of the time. This article is just for those 1% of cases.

Please follow and like us:
Pin Share