带block/proc/lambda的Ruby双管道赋值?

带block/proc/lambda的Ruby双管道赋值?,ruby,syntax,operators,variable-assignment,block,Ruby,Syntax,Operators,Variable Assignment,Block,能写出来真是太好了 @foo ||= "bar_default" 或 但我一直在寻找是否有一种方法来写类似的东西 @foo ||= do myobject.attr = new_val myobject.other_attr = other_new_val myobject.bar(args) end @foo = if !@foo.nil? @foo else myobject.attr = new_val m

能写出来真是太好了

@foo ||= "bar_default"

但我一直在寻找是否有一种方法来写类似的东西

@foo ||= do
  myobject.attr = new_val
  myobject.other_attr = other_new_val
  myobject.bar(args)
end
@foo = if !@foo.nil?
         @foo
       else
         myobject.attr = new_val
         myobject.other_attr = other_new_val
         myobject.bar(args)
       end
在实际功能代码中大致等同于

@foo ||= do
  myobject.attr = new_val
  myobject.other_attr = other_new_val
  myobject.bar(args)
end
@foo = if !@foo.nil?
         @foo
       else
         myobject.attr = new_val
         myobject.other_attr = other_new_val
         myobject.bar(args)
       end

我想我可以编写自己的全局方法,如“getblock”来包装并返回任何常规块的结果,但我想知道是否已经有一种内置的方法来实现这一点。

您可以使用
开始
结束

@foo ||= unless @foo
  myobject.attr = new_val
  myobject.other_attr = other_new_val
  myobject.bar(args)
end
@foo ||= begin
  # any statements here
end

或者也许考虑把块的内容分解成一个单独的方法。

我通常这样写:

@foo ||= (
  myobject.attr = new_val
  myobject.other_attr = other_new_val
  myobject.bar(args)
)

谢谢,我不知道为什么我没有想到这个。它都是线程安全的吗?