我注意到我需要在块之前将括号括起来传递给Ruby方法。 Wat是什么原因?归结为最小的例子来说明我的意思:
def test a
yield 100
end
test 50 { |x| x*x + 2 } # Gives an error in irb!
test(50) { |x| x*x + 2 } # Gives no error!
我不明白为什么Ruby会抱怨第一个案例。错误如下:
SyntaxError: compile error
(irb):18: syntax error, unexpected '{', expecting $end
答案 0 :(得分:3)
以下是可能出现歧义的一个例子:
def foo(val = "default", &block)
# ...
end
哈希和块文字都是使用{ ... }
因此,如果您致电foo {}
- 您是否将空哈希传递给val
参数(block
成为nil
),或者您是否将空块传递给block
参数(val
成为"default"
)?
答案 1 :(得分:2)
这与{
... }
有时会分隔一个块,有时是一个Hash文字的事实有关。消除这两种用途的歧义有一些奇怪的副作用。
如果您使用do
... end
,则无法使用括号:
test 50 do |x| x*x + 2 end
答案 2 :(得分:1)
Ruby不知道你想用块做什么。
当Ruby看到:
test 50 { |x| x*x + 2 } # Gives an error in irb!
它认为该块已附加到50
,这就是您收到错误的原因。
当你将50
放在括号中时,Ruby知道该块没有绑定到50
。
test(50) { |x| x*x + 2 } # Gives no error!
为了理智,99.9%的时间我将参数放在括号内。我不想记住绑定规则,并确保Ruby能做正确的事情。此外,括号可以帮助我们查看哪些参数有助于调试。
答案 3 :(得分:-2)
使用块表示法时,块将针对开头{
左边的值运行。因此,在您的第一个示例中,您尝试将50 { |x| ... }
传递给test
方法。由于50
不是Enumerable对象,因此您收到错误。