块定义 – 大括号和do-end之间的区别?

任何人都可以解释为什么下面的代码中止与一个错误

irb(main):186:0> print ((1..10).collect do |x| x**2 end) SyntaxError: (irb):186: syntax error, unexpected keyword_do_block, expecting ')' print ((1..10).collect do |x| x**2 end) ^ (irb):186: syntax error, unexpected keyword_end, expecting $end print ((1..10).collect do |x| x**2 end) ^ from /usr/bin/irb:12:in `<main>' 

而下面的代码具有相同的function如预期的那样工作?

 irb(main):187:0> print ((1..10).collect { |x| x**2 }) [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]=> nil 

我确实相信花括号“{}”可以在块定义中任意replace“do end”。

我知道我可以通过省略print方法和第一个括号之间的空格来“修复”第一个调用,但是我对它的行为有所不同的解释感兴趣。

差异是优先:

 # Equivalent to puts( (1..10).map { |i| i*2 } ) > puts (1..10).map { |i| i*2 } 2 4 6 8 10 12 14 16 18 20 => nil # Equivalent to puts( (1..10).map ) { |i| i*2 } > puts (1..10).map do |i| i*2 end #<Enumerator:0x928f24> => nil 

在第一种情况下,块被传递给map ,一切正常。 在第二种情况下,块被传递给puts ,这对它没有任何作用。 map不会收到一个块,只是返回一个枚举器。

至于语法错误,如果删除print(一切正常)之间的空格,

不同之处在于,ruby是否将方括号作为方法参数分隔符来处理,或者是否是generics语句分组。 我不确定在那里的确切区别,但它是微妙的,烦人的

SO上已经有了最终的 答案 。

不幸的是,这绝对不是 Ruby背后的最理想的哲学的一个很好的certificate。