传递给每个代码块的代码块使用括号而不是'do' - 'end'(ruby)

时间:2011-07-16 15:27:36

标签: ruby

我最近开始学习ruby,我知道你可以使用这两种语法的代码块。但我刚发现一个我不理解的案例:

#my_hash is a hash in which the keys are strings and the values arrays, but dont think about the specifics fo the code

#if I run my code like this, it works perfectly

my_hash.each do |art|
  puts mystring.gsub(art[0]).each {
    art[1][rand(art[1].length) -1]
  }
end

#but if I use this, it prints "Enumerator"

my_hash.each do |art|
  puts mystring.gsub(art[0]).each do
    art[1][rand(art[1].length) -1]
  end
end

是因为你不能窝对端吗? 我正在使用1.9

3 个答案:

答案 0 :(得分:7)

puts mystring.gsub(art[0]).each do
  art[1][rand(art[1].length) -1]
end

在这里,您调用了puts而没有parens,do ... end指的是puts方法,它对块没有任何作用并打印mystring.gsub(art[0]).each(带有{{1} }})。

使用最近的方法调用Enumerator。变得丑陋,但你可以用{ ... }

来做
do ... end

或者,更好的是,将结果放在变量中并打印变量:

puts(mystring.gsub(art[0]).each do
  art[1][rand(art[1].length) -1]
end)

无论如何,var = mystring.gsub(art[0]).each do art[1][rand(art[1].length) -1] end puts var 不会更改对象,它只是迭代并返回对象本身。您可能需要each方法,对其进行测试。

答案 1 :(得分:3)

扩展Scott的回复,并引用Jim Weirich

  

不同之处在于它们落在运算符优先级表中的位置。 {}比do / end更紧密。例如:

     

f g {}

     

被解析为f(g {}),其中大括号属于方法g。另一方面,

     

f g do end

     

被解析为f(g)do end,其中大括号属于方法f。只有在省略括号并产生歧义时才重要。

答案 2 :(得分:2)

嵌套do / end对在Ruby中是完全合法的,但是你遇到了{}和do / end之间的一个微妙的优先级问题。

您可以阅读更多关于here的内容。