6

If I run the following code, the first two lines return what I expect. The third, however, returns a binary representation of 2.

2.to_s      # => "2"
2.to_s * 2  # => "22"
2.to_s *2   # => "10" 

I know that passing in 2 when calling to_s will convert my output to binary, but why is to_s ignoring the * in the third case? I'm running Ruby 1.9.2 if that makes any difference.

Simone Carletti
  • 173,507
  • 49
  • 363
  • 364
slapthelownote
  • 4,249
  • 1
  • 23
  • 27

2 Answers2

7

Right, as Namida already mentioned, Ruby interprets

2.to_s *2

as

2.to_s(*2)

as parentheses in method calls are optional in Ruby. Asterisk here is so-called splat operator.

The only puzzling question here is why *2 evaluates to 2. When you use it outside of a method call, splat operator coerces everything into an array, so that

a = *2

would result with a being [2]. In a method call, splat operator is doing the opposite: unpacks anything as a series of method arguments. Pass it a three member array, it will result as a three method arguments. Pass it a scalar value, it will just be forwarded on as a single parameter. So,

2.to_s *2

is essentially the same as

2.to_s(2)
Jan
  • 11,636
  • 38
  • 47
Mladen Jablanović
  • 43,461
  • 10
  • 90
  • 113
0

In the third line you're calling the to_s method with the "splat" of 2, which evaluates to 2 (in a method call), and hence returns the number in a different base.

Filipe Miguel Fonseca
  • 6,400
  • 1
  • 31
  • 26
  • Apparently that depends on the ruby version. The result of a = *2 is different from ruby 1.8.7 to 1.9. But since @slapthelownote stated he was using 1.9.2 you stand correct. – Filipe Miguel Fonseca Oct 01 '12 at 08:28