2011-11-02 37 views
7

在阅读Programming Ruby,我跑过这个代码片段:为什么Ruby让我在不指定字符串的情况下调用String方法?

while gets 
    num1, num2 = split /,/ 
end 

虽然我直观地了解它做什么,我听不懂的语法。 'split'是String类中的一个方法 - 用Ruby的说法,该字符串是上述场景中'split'消息的接收者?

我可以在文档中看到'gets'将结果赋给变量$ _,所以我的猜测是它隐式地使用$ _作为接收者 - 但是一大堆Google搜索未能确认猜测。如果是这样的话,我很想知道没有明确接收者的情况下调用什么方法的一般规则。

我尝试了irb中的代码,添加了一些诊断put操作,并且验证了实际行为是您所期望的 - num1和num2分配了由逗号分隔的输入值。

回答

6

Ruby 1.8的方法Kernel#split([pattern [, limit]])$_.split(pattern, limit)相同,并且gets设置值$_

4

你基本上已经用你的解释来钉牢它(至少对于1.8.7,1.9.3给了我的一个NoMethodError),但恕我直言,这是可怕的Ruby(或者可能是从Perl切换过来的人)。如果你把它改写为这样的事情,它变得更加清晰:

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

的方法的一般规则通话,而接收器是它们发送到self,无论那是在目前情况下。在顶层,它是前面提到的main$_循环Perlism似乎不在1.9。

+1

'$ _'在Ruby 1.9中仍然存在(并被'gets'使用),但'Kernel#split'方法消失了。它以前的工作原理并不是因为在'$ _'上调用'split',而是因为它在'Kernel'上被调用。 –

+0

是的,我说得很糟糕。 –

+0

@MichelleTilley:它正在'self'上调用,此时'main',而不是'Kernel'。 'main'的类是'Object','Object'继承自'Kernel'(更准确地说* *在'Kernel'中混合),但这绝不意味着该方法在'Kernel'上被调用。 (你*理论上可以在'Kernel'上调用它,因为'Kernel'的类是'Module','Module'继承自'Object',它在'Kernel'中混合,因此'Kernel'是它自己的一个实例,但这是一个非常令人困惑的方式来说话。) –

相关问题