DEV Community

Cover image for Ruby function design and other stuff I like ranting about
anes
anes

Posted on

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:
Image description

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;
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"]
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

But you get something completely different:

irb(main):018> "12".sum
=> 99
Enter fullscreen mode Exit fullscreen mode

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

irb(main):027> "2".sum
=> 50
irb(main):028> "1".sum
=> 49
Enter fullscreen mode Exit fullscreen mode

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>'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

?!

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

irb(main):038> 2e10.class
=> Float
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)