繁体   English   中英

在Ruby中使用什么是|| = begin ... end block?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM