Ruby do/end vs 大括号
Posted
技术标签:
【中文标题】Ruby do/end vs 大括号【英文标题】:Ruby do/end vs braces 【发布时间】:2011-07-27 16:16:56 【问题描述】:为什么这个 map 表达式会根据我使用大括号还是 do/end 产生不同的结果?
a = [1,2,3,4,5]
p a.map |n|
n*2
#=> [2,4,6,8,10]
p a.map do |n|
n*2
end
#=> [1,2,3,4,5]
【问题讨论】:
直到今天仍然有效 这能回答你的问题吗? Using do block vs braces 【参考方案1】:那是因为第二行被解释为:
p(a.map) do ... end
代替:
p(a.map do ... end)
在这种情况下,语法不明确,do
的绑定似乎不如 强。
【讨论】:
@Grandpa 这不是特别关于“p”。这是关于方法的参数/块和之间的强度/优先级,做结束 如何才能将do...end
与多行块一起使用,以便map
将其作为参数?大括号 - 根据您的建议 - 不会这样做,Ruby 会抛出错误,unexpected keyword_do_block
甚至整个块都是一行。
@karatedog:你可能需要在这里使用一个中间变量,因为解析器不支持你想要的。
@DarkDust 谢谢,但当 Enumerator 无限时我不能使用中间变量,因为我必须事先知道我应该在该中间变量中生成多少项目。
我不明白你的意思,当然你可以foo = a.map do ... end ; p(foo)
。这是完全相同的语义,因为map
总是需要先聚合一个数组才能传递。然后将该数组存储在变量中或作为参数传递给另一个方法都没有区别,无论如何都需要先创建数组。【参考方案2】:
这与 字符和
do
关键字的关联性不同有关。
在第一种情况下,块被解释为map
函数的块参数。 map 函数的结果是p
函数的参数。
在第二种情况下,块被解释为p
函数的块参数,而a.map
被解释为p
函数的第一个参数。由于a.map
的计算结果为a
,因此将打印原始数组。在这种情况下,该块实际上被忽略了。
【讨论】:
【参考方案3】:使用do/end
语法,您将块作为第二个参数传递给p
,而不是传递给地图。您会得到相同的结果:
p a.map
p
忽略该块,因为它不会在 inspect
上产生任何内容。
【讨论】:
以上是关于Ruby do/end vs 大括号的主要内容,如果未能解决你的问题,请参考以下文章