Code block passed to each works with brackets but

2019-01-01 14:08发布

I recently started learning ruby, and I understood that you coud use code blocks with both of these syntaxes. But I just found a case which I dont understand:

#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

Is it because you cant nest do-end pairs? I am using 1.9

标签: ruby
3条回答
素衣白纱
2楼-- · 2019-01-01 14:28
puts mystring.gsub(art[0]).each do
  art[1][rand(art[1].length) -1]
end

Here you called puts without parens, the do ... end refers to the puts method, that does nothing with a block and prints mystring.gsub(art[0]).each (with is a Enumerator).

The { ... } is called with the nearest method. Becomes ugly, but you can do it with do ... end:

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

Or, better, put the result in a variable and print the variable:

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

Anyway, the each don't changes the object, it just iterate and returns the object itself. You may be wanting the map method, test it.

查看更多
旧时光的记忆
3楼-- · 2019-01-01 14:29

Expanding on Scott's reply, and quoting Jim Weirich:

The difference is where in the operator precedence table they fall. { } binds tighter than do/end. For example:

f g { }

is parsed as f(g { }), where the braces belong to the method g. On the other hand,

f g do end

is parsed as f(g) do end, where the braces belong to the method f. It only matters when you omit parenthesis and create ambiguities.

查看更多
心情的温度
4楼-- · 2019-01-01 14:32

Nesting do/end pairs is perfectly legal in Ruby, but you are coming up against a subtle precedence issue between { } and do/end.

You can read a little more about that here.

查看更多
登录 后发表回答