Ruby 不同的行为取决于方块类型
Ruby different behavior depend of block type
美好的一天。
我对同一块代码有不同的行为取决于块语法大括号或 do/end 的类型。 do/end 的块刚刚跳过,没有任何错误通知:
带花括号的块只是实现并且 p
打印 one Ruby is a COOL language!
:
p "rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) {
"one " + .capitalize + " %s %s %s %s!" % [,,.upcase,]
}
刚刚跳过 do/end 中的 'same' 代码片段,p
显示 Enumerator
<Enumerator: "rubyisacoollanguage":gsub(/(ruby)(is)(a)(cool)(language)/)>
:
p "rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) do
"two " + .capitalize + " %s %s %s %s!" % [,,.upcase,]
end
我认为这是因为 p
在第二种情况下它消除了块。当我在块中添加 p
时,事情就变得清楚了。第一个块的数据打印了 2 次,而第二个块的数据根本没有打印。
p "rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) {
p "one " + .capitalize + " %s %s %s %s!" % [,,.upcase,]
}
p "rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) do
p "two " + .capitalize + " %s %s %s %s!" % [,,.upcase,]
end
这对我来说是非常奇怪和不可预测的行为。没有错误,只是跳过了部分代码。为什么会这样?
Ruby 松散的语法规则的问题在于,有时它会在块属于谁时被绊倒。由于歧义,p
和 gsub
都可以 "own" 该块。 do
方法被分配给 p
,而 { ... }
方法被固定在 gsub
。
这可能是由于某些运算符优先类型规则所致,但由于该块本身不是运算符,我不确定我现在是否可以找到该特定行为的参考。
如果有歧义,最好根据解释的方式避免,而是更具体:
rv = "rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) do
"two" + .capitalize + " %s %s %s %s!" % [,,.upcase,]
end
p rv
这里rv =
不能拿块所以它不会最终无意中抓住它。
您也可以这样做:
p(
"rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) do
"two" + .capitalize + " %s %s %s %s!" % [,,.upcase,]
end
)
你在哪里非常清楚谁得到了什么。
Ruby 通常会给你两种表达同一事物的方式。 block
与 p
调用关联,而不是 gsub
调用。
运算符优先级。
Why does it happen?
因为 {} 和 do/end 有不同的优先级。 {} 是 "stronger"。如 "is associated to the nearest method call"。所以这个
p foo {
something
}
是这样看的
p (foo {
something
})
而do/end是这样的
p(foo) do
something
end
No error, just skip part of the code
是的,由于 ruby 的另一个特点。这是 "you can pass a block to ANY method. It is then that method's responsibility to use or ignore it." 这里 p
不期望一个块并简单地忽略它。
美好的一天。 我对同一块代码有不同的行为取决于块语法大括号或 do/end 的类型。 do/end 的块刚刚跳过,没有任何错误通知:
带花括号的块只是实现并且 p
打印 one Ruby is a COOL language!
:
p "rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) {
"one " + .capitalize + " %s %s %s %s!" % [,,.upcase,]
}
刚刚跳过 do/end 中的 'same' 代码片段,p
显示 Enumerator
<Enumerator: "rubyisacoollanguage":gsub(/(ruby)(is)(a)(cool)(language)/)>
:
p "rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) do
"two " + .capitalize + " %s %s %s %s!" % [,,.upcase,]
end
我认为这是因为 p
在第二种情况下它消除了块。当我在块中添加 p
时,事情就变得清楚了。第一个块的数据打印了 2 次,而第二个块的数据根本没有打印。
p "rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) {
p "one " + .capitalize + " %s %s %s %s!" % [,,.upcase,]
}
p "rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) do
p "two " + .capitalize + " %s %s %s %s!" % [,,.upcase,]
end
这对我来说是非常奇怪和不可预测的行为。没有错误,只是跳过了部分代码。为什么会这样?
Ruby 松散的语法规则的问题在于,有时它会在块属于谁时被绊倒。由于歧义,p
和 gsub
都可以 "own" 该块。 do
方法被分配给 p
,而 { ... }
方法被固定在 gsub
。
这可能是由于某些运算符优先类型规则所致,但由于该块本身不是运算符,我不确定我现在是否可以找到该特定行为的参考。
如果有歧义,最好根据解释的方式避免,而是更具体:
rv = "rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) do
"two" + .capitalize + " %s %s %s %s!" % [,,.upcase,]
end
p rv
这里rv =
不能拿块所以它不会最终无意中抓住它。
您也可以这样做:
p(
"rubyisacoollanguage".gsub(/(ruby)(is)(a)(cool)(language)/) do
"two" + .capitalize + " %s %s %s %s!" % [,,.upcase,]
end
)
你在哪里非常清楚谁得到了什么。
Ruby 通常会给你两种表达同一事物的方式。 block
与 p
调用关联,而不是 gsub
调用。
运算符优先级。
Why does it happen?
因为 {} 和 do/end 有不同的优先级。 {} 是 "stronger"。如 "is associated to the nearest method call"。所以这个
p foo {
something
}
是这样看的
p (foo {
something
})
而do/end是这样的
p(foo) do
something
end
No error, just skip part of the code
是的,由于 ruby 的另一个特点。这是 "you can pass a block to ANY method. It is then that method's responsibility to use or ignore it." 这里 p
不期望一个块并简单地忽略它。