David
David

Reputation: 7486

Getting perplexing results in Ruby trying to do integer.to_s to convert it to a string

Very simply put, when I try to insert an integer into a method, then convert it into a string, and print out the first character into the string, I get the number in the [0] slot + 48. Without fail, I get slot + 48. I'm extremely perplexed because I believe I should be getting the number in that slot. Example:

def print_number(num)
  number = num.to_s
  print number[0]
end

Without fail, I will receive x + 48.

print_number(2) #=> 50 (Believe I should get 2)
print_number(5) #=> 53 (Believe I should get 5)
print_number(123) #=> 49 (Believe I should get 4)
print_number(42) #=> 52 (Believe I should get 5)
print_number(22) #=> 50 (Believe I should get 5)
print_number(1) #=> 49 (Believe I should get 5)

Why?

Upvotes: 0

Views: 138

Answers (3)

Holger Just
Holger Just

Reputation: 55898

When accessing Strings like you do, there is a difference between Ruby 1.8 and Ruby 1.9. In Ruby 1.9, you get the first character in whatever encoding the string has (which can consist of multiple bytes when e.g. using UTF-8).

Ruby 1.8 is not encoding aware, thus string[0] always returns a representation of the first byte of the string, in this case, the numeric value of the first byte. If you have a look at an ASCII table, you will notice, that the character 1 has the decimal value of 49 there.

If you use Ruby 1.8, you can use either one of these variants:

"123".chars.to_a[0]
# or
"123".chars.first
# or
"123"[0, 1]

Upvotes: 1

This is because in Ruby 1.8, String#[] returns the code of the character in that position, e.g. 50 is the ASCII code for 2.

Upvotes: 0

sawa
sawa

Reputation: 168249

I guess you are using Ruby < 1.9. That is the behavior in it. If you want to get what you expect, upgrade to Ruby >= 1.9. Or, if you insist on using Ruby < 1.9, do number[0, 1] instead of number[0].

Upvotes: 0

Related Questions