[英]What is use of ||= begin…end block in Ruby?
这两个代码片段有什么区别:
def config
@config ||= begin
if config_exists?
@config = return some value
else
{}
end
end
end
和
def config
@config ||= method
end
def method
if config_exists?
return some value
else
{}
end
end
我对“ begin
... end
”块感到困惑。 输出有什么不同吗? 如果没有,那么在这里使用begin
... end
块有什么用?
首先,您需要知道定义的方法本身包含begin ... end
块的功能。
在异常处理的上下文中, def method_name ... end
在功能上等同于begin ... end
。 例如,两者都可以包括rescue
声明。
您共享的两个代码块实际上是相同的,并且在一个代码中没有任何好处......除非您的method
在多个地方需要。 在这种情况下,通过将逻辑放入单个方法并从多个其他位置调用它来干掉代码。
在您的情况下,您甚至可以省略begin ... end
块:
@config ||=
if config_exists?
return_some_value
else
{}
end
或者,使用三元if :
@config ||= config_exists? ? return_some_value : {}
它的输出有什么不同吗?
它可能会有所不同,因为与def ... end
不同, begin ... end
块不会创建新的变量范围。
这是一个人为的例子:
def foo
a = 456 # doesn't affect the other a
end
a = 123
b = foo
p a: a, b: b #=> {:a=>123, :b=>456}
与:
a = 123
b = begin
a = 456 # overwrites a
end
p a: a, b: b #=> {:a=>456, :b=>456}
使用||= begin...end
可以记住 begin...end
运行的结果。 这对于缓存资源密集型计算的结果很有用。
唯一不同的是,如果引发异常。 例如,假设config_exists?
存在问题config_exists?
方法调用。 如果它在第一个示例中引发异常,则@config
var将设置为{}
。 在第二个例子中,如果同样的事情发生,你的程序将崩溃。
作为旁注,这里不需要return
关键字。 实际上,该示例应如下所示。 这是假设我理解意图。
def config
@config ||=
begin
if config_exists?
some_value
else
{}
end
rescue
{}
end
end
和
def config
@config ||= method
end
def method
if config_exists?
some_value
else
{}
end
end
这两个例子中是完全一样的,不同之处,如果将引发一个例外@config
将仍然被设置为= some_value
在第一个例子。
此外,应该注意的是,如果@config
已经有值,则不会发生任何事情。 ||=
运算符与:
@config = some_value if @config.nil?
如果当前为零,则仅将变量设置为此值。
希望这有用,我正确理解你的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.