Bruce
Bruce

Reputation: 8430

Why does Ruby let me call a String method without specifying the string?

While reading Programming Ruby, I ran across this code snippet:

while gets
  num1, num2 = split /,/
end

While I intuitively understand what it does, I don't understand the syntax. 'split' is a method on the String class - in Ruby parlance, which string is the receiver of the 'split' message in the scenario above?

I can see in the docs that 'gets' assigns its result to the variable $_, so my guess is that it is implicitly using $_ as the receiver - but a whole bunch of Google searching has failed to confirm that guess. If that is the case, I'd love to know what general rule for methods called without an explicit receiver.

I did try the code in irb, with some diagnostic puts calls added, and I verified that the actual behavior is what you would expect - num1 and num2 get assigned values that were input separated by a comma.

Upvotes: 7

Views: 167

Answers (2)

Michelle Tilley
Michelle Tilley

Reputation: 159125

Ruby 1.8 has a method Kernel#split([pattern [, limit]]) which is identical to $_.split(pattern, limit), and gets sets the value of $_.

Upvotes: 6

Michael Kohl
Michael Kohl

Reputation: 66857

You basically nailed it with your explanation (at least for 1.8.7, 1.9.3 gave me a NoMethodError for main), but IMHO that's horrible Ruby (or maybe someone switching over from Perl). If you rewrite it to something like this, it becomes a lot clearer:

while input = gets.chomp
  num1, num2 = input.split(/,/)
end

The general rule for method calls without a receiver is that they are sent to self, whatever that may be in the current context. In the top level it's the aforementioned main, the $_ looping Perlism seems to be gone in 1.9.

Upvotes: 4

Related Questions