Ruby的不同行为取决于块类型

Dmi*_*iev 1 ruby block

美好的一天.我有相同的代码块的不同行为取决于块语法花括号或do/end的类型.刚跳过do/end的块没有任何错误通知:

带有大括号的块只是实现和p打印one Ruby is a COOL language!:

p "rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) {
   "one " + $1.capitalize + " %s %s %s %s!" % [$2,$3,$4.upcase,$5]
}
Run Code Online (Sandbox Code Playgroud)

do/end中的"相同"代码段只是跳过,并p告诉我Enumerator <Enumerator: "rubyisacoollanguage":gsub(/(ruby)(is)(a)(cool)(language)/)>:

p "rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) do
    "two " + $1.capitalize + " %s %s %s %s!" % [$2,$3,$4.upcase,$5]
end
Run Code Online (Sandbox Code Playgroud)

我认为这是因为p在第二种情况下它会消除阻塞.当我添加p内部块时,事情变得清晰.来自第一个块的数据打印2次,而来自第二个的数据根本没有被打印.

p "rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) {
   p "one " + $1.capitalize + " %s %s %s %s!" % [$2,$3,$4.upcase,$5]
}
p "rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) do
    p "two " + $1.capitalize + " %s %s %s %s!" % [$2,$3,$4.upcase,$5]
end
Run Code Online (Sandbox Code Playgroud)

这对我来说是非常奇怪和不可预测的行为.没有错误,只是跳过部分代码.为什么会这样?

Ser*_*sev 5

为什么会这样?

因为{}和do/end具有不同的优先级.{}是"更强".如"与最近的方法调用相关联".所以这

p foo {
  something
}
Run Code Online (Sandbox Code Playgroud)

就像这样.

p (foo {
  something
})
Run Code Online (Sandbox Code Playgroud)

do/end就是这样的

p(foo) do
  something
end
Run Code Online (Sandbox Code Playgroud)

没有错误,只是跳过部分代码

是的,由于红宝石的另一个特点.这是"你可以将一个块传递给任何方法.然后该方法是使用或忽略它的责任." 这里p没有期待一个块,只是忽略它.