首页 > 解决方案 > Ruby 不同的行为取决于块类型

问题描述

再会。我对同一块代码有不同的行为取决于块语法花括号或 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]
}

刚刚跳过 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

我认为这是因为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

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

标签: rubyblock

解决方案


为什么会这样?

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

p foo {
  something
}

是这样看的。

p (foo {
  something
})

而做/结束是这样的

p(foo) do
  something
end

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

是的,由于 ruby​​ 的另一个特性。即“您可以将块传递给任何方法。然后该方法负责使用或忽略它。” 这里p不期望一个块并简单地忽略它。


推荐阅读