为什么 `each do` 会在带注释的方法定义中导致语法错误?
Why does `each do` cause a syntax error inside of an annotated method definition?
此代码:
private def not_ok
collection.each do |x|
puts x
end
end
导致语法错误:
syntax error, unexpected keyword_do_block, expecting keyword_end
更新:这是使用 MRI Ruby 2.1.0。显然,此行为是特定于版本的,并已在更高版本中得到修复,包括 2.1.1 (!)。 (感谢@Amadan 和@JörgWMittag 指出这一点。)
为什么它会引发语法错误,如何在不将 do
块更改为 {}
块的情况下不给出语法错误?
为了比较,这些变体不会导致语法错误:
def ok
collection.each do |x|
puts x
end
end
private def ok
collection.each { |x|
puts x
}
end
private def ok
each do |x|
puts x
end
end
自从了解到 def
表达式 return 可以传递给其他方法的符号后,我开始使用 private
单独注释我的更多方法,而不是单独使用 public
和 class 中的 private
部分(我觉得不太容易维护),并且 运行 多次遇到这个问题——任何时候方法包含 do/end
块。
在旧版本的 Ruby 上,do
/end
块似乎存在优先级问题。
您可以通过将 def
表达式的 return 值分配给一个变量,然后将该变量传递给对 Module#private
:[=28= 的调用来解决这个问题]
var = def not_ok
collection.each do |x|
puts x
end
end
private var
但是请注意,在旧版本的 Ruby 中,方法定义表达式的 return 值是实现定义的,因此您不知道上面的代码会做什么。 MRI、YARV、MacRuby、MagLev、JRuby 和 IronRuby 将 return nil
作为 def
表达式的结果,这将 raise
变成 TypeError
,因为 Module#private
只需要 Symbol
或 String
秒。 Rubinius 将 return 一个 CompiledMethod
对象表示该方法的编译代码,但同样,这将 raise
来自 Module#private
.
的 TypeError
只有在 Ruby 的最新版本中,def
表达式才会计算为 Symbol
,但是,在 Ruby 的那些最新版本中,优先级问题已解决也已修复,以便您的代码正常工作。
它适用于 YARV 2.2.0 和 JRuby-9.0.0.0-dev,但不适用于 JRuby 1.7.18 和 Rubinius 2.2.0(最后一个可能是一个错误,因为它声称与 Ruby 2.1.0).
兼容
此代码:
private def not_ok
collection.each do |x|
puts x
end
end
导致语法错误:
syntax error, unexpected keyword_do_block, expecting keyword_end
更新:这是使用 MRI Ruby 2.1.0。显然,此行为是特定于版本的,并已在更高版本中得到修复,包括 2.1.1 (!)。 (感谢@Amadan 和@JörgWMittag 指出这一点。)
为什么它会引发语法错误,如何在不将 do
块更改为 {}
块的情况下不给出语法错误?
为了比较,这些变体不会导致语法错误:
def ok
collection.each do |x|
puts x
end
end
private def ok
collection.each { |x|
puts x
}
end
private def ok
each do |x|
puts x
end
end
自从了解到 def
表达式 return 可以传递给其他方法的符号后,我开始使用 private
单独注释我的更多方法,而不是单独使用 public
和 class 中的 private
部分(我觉得不太容易维护),并且 运行 多次遇到这个问题——任何时候方法包含 do/end
块。
在旧版本的 Ruby 上,do
/end
块似乎存在优先级问题。
您可以通过将 def
表达式的 return 值分配给一个变量,然后将该变量传递给对 Module#private
:[=28= 的调用来解决这个问题]
var = def not_ok
collection.each do |x|
puts x
end
end
private var
但是请注意,在旧版本的 Ruby 中,方法定义表达式的 return 值是实现定义的,因此您不知道上面的代码会做什么。 MRI、YARV、MacRuby、MagLev、JRuby 和 IronRuby 将 return nil
作为 def
表达式的结果,这将 raise
变成 TypeError
,因为 Module#private
只需要 Symbol
或 String
秒。 Rubinius 将 return 一个 CompiledMethod
对象表示该方法的编译代码,但同样,这将 raise
来自 Module#private
.
TypeError
只有在 Ruby 的最新版本中,def
表达式才会计算为 Symbol
,但是,在 Ruby 的那些最新版本中,优先级问题已解决也已修复,以便您的代码正常工作。
它适用于 YARV 2.2.0 和 JRuby-9.0.0.0-dev,但不适用于 JRuby 1.7.18 和 Rubinius 2.2.0(最后一个可能是一个错误,因为它声称与 Ruby 2.1.0).
兼容