我想要一种方法来退出开始/结束块,同时仍然分配其结果分配给的变量。
def foo
@foo ||= begin
puts "running"
return "leaving early" if true # would be some sort of calculation
# Other calculations
end
end
我希望发生什么
> foo
running
=> leaving early
> foo
=> leaving early
实际发生了什么
> foo
running
=> leaving early
> foo
running
=> leaving early
该代码不起作用,因为
return
退出整个方法而不设置 @foo
。使用 break
或 next
只能在循环中使用。开始内有什么工作会阻碍我的思考方式吗?
我目前可以做到但希望避免的方法:
似乎有很多关于打破区块的相关问题,但我找不到一个可以回答这个特定版本的问题(也许是因为这是不可能的)。
我认为,如果您将所有这些逻辑放入其自己的方法中,您将为自己节省很多冲突:
def foo
@foo ||= compute_foo
end
def compute_foo
puts "running"
return "leaving early" if true # would be some sort of calculation
# Other calculations
end
这将计算与记忆解耦,使其更容易测试和推理,并且这是 Ruby 和其他语言中相当常见的设计模式。
当然,有多种方法可以满足您的要求。最明显的解决方案是立即调用的匿名过程:
def foo
@foo ||= (proc do
puts "running"
next "leaving early" if true # would be some sort of calculation
# Other calculations
end)[] # or .call or .()
end
但是您肯定不会为您自己或此代码的任何未来维护者带来任何好处。
您可以使用
loop do ... end
结构代替 begin ... end
break <value>
从块返回值。
def foo
@foo ||= loop do
puts "running"
break "leaving early" if true # would be some sort of calculation
# Other calculations
break "leaving at the end"
end
end
这将为您带来预期的结果:
> foo
running
=> leaving early
> foo
=> leaving early