Ruby function design and other stuff I like ranting about
Tags: ruby, watercooler
Published: 2024-06-04 22:09:31

## 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dug879xycl8931yoc6s4.png)

## 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:
```java
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:
```ruby
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`:
```ruby
irb(main):012> "a".to_i
=> 0
irb(main):013> "fdsgsdf".to_i
=> 0
```

That leads to some weird (but expected) behaviour:
```ruby
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:
```ruby
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:
```ruby
irb(main):018> "12".sum
=> 12
irb(main):018> "12".sum
=> 3 # Because 1 + 2 = 3
```
But you get something completely different:
```ruby
irb(main):018> "12".sum
=> 99
```
And now why does this happen you might as?
Because of this:
```ruby
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:
```ruby
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.