传递给每个代码块与括号,但不是'做' – '结束'(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 

这是因为你不能嵌套do-end对吗? 我正在使用1.9

 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 (使用Enumerator )。

用最近的方法调用{ ... } 。 变得丑陋,但你可以做到这do ... end

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

或者,最好把结果放在一个variables中,然后打印variables:

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

无论如何, each都不会改变对象,它只是迭代并返回对象本身。 你可能想要map方法,testing它。

扩展斯科特的答复,并引用吉姆Weirich :

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

fg {}

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

fg做结束

被parsing为f(g)结束,其中大括号属于方法f。 只有当你省略括号并产生歧义时才重要。

嵌套do / end对在Ruby中是完全合法的,但是您正面临{}和do / end之间的细微优先问题。

你可以在这里阅读更多。