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

发布于 2024-11-10 16:00:28 字数 735 浏览 1 评论 0原文

任何人都可以解释为什么以下代码会因错误而中止,

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>'

而以下具有相同功能的代码会按预期工作?

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

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

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

can anybody explain why the following code aborts with an error

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>'

whereas following code with the same functionality works as expected ?

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

I did believed curly-braces "{ }" can substitute "do end" arbitrarily at block
definition.

I know I can "fix" the first call by omitting a space between print
method and the first parenthesis, but I'm interested in an explanation
why it behaves different.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

顾挽 2024-11-17 16:00:28

区别在于优先级:

# 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​​ 是否将括号视为方法参数分隔符,或者是否将其视为方法参数分隔符。通用语句分组。我不确定其中的确切区别,但它很微妙且烦人

The difference is precedence:

# 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 

In the first case, the block is passed to map, and everything works properly.
In the second case, the block is passed to puts, which doesn't do anything with it. map doesn't receive a block and just returns an enumerator.

As for the syntax error, if you remove the space between print and ( everything works ;)

The difference is whether ruby is treating your parentheses as method argument delimiters, or whether it's a generic statement grouping. I'm not sure of the exact difference there but it's subtle and annoying

落日海湾 2024-11-17 16:00:28

有一个终极 答案已经在SO上了。

不幸的是,这绝对不是很好地展示了 Ruby 背后的最少惊喜哲学。

There is an ultimate answer already on SO.

Unfortunately this is definitely not a good demonstration of least surprise philosophy behind Ruby.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文