我的功能bar
得到一個塊,我想運行這個塊而不允許它到return
。我如何通過修改下面的bar
來完成此操作,並保持其他所有操作(包括foo
)完好無損?如何在Ruby中返回LocalJumpError?
def bar()
yield
end
def foo()
bar do
p "it"
return # This works. But I'd like to get LocalJumpError.
end
end
foo
我的功能bar
得到一個塊,我想運行這個塊而不允許它到return
。我如何通過修改下面的bar
來完成此操作,並保持其他所有操作(包括foo
)完好無損?如何在Ruby中返回LocalJumpError?
def bar()
yield
end
def foo()
bar do
p "it"
return # This works. But I'd like to get LocalJumpError.
end
end
foo
基於在其他的答案的建議,我已成功地解決了這個問題:
def bar()
has_returned = true
begin
x = yield
has_returned = false
x
rescue
has_returned = false
raise
ensure
raise LocalJumpError if has_returned
end
end
def foo()
bar do
p "it"
return # This makes bar raise a LocalJumpError.
end
end
foo
那麼,當您嘗試,並通過一個塊用
return
到
Proc
(而不是一個
lambda
)獲得
LocalJumpError
。
你可以逃脫不改變foo
,除了它是如何調用,如果你這樣做
def bar()
Proc.new
end
def foo()
bar do
p "it"
return
end
end
foo[]
,給出了一個LocalJumpError
。
無論如何,
this article可能會有所幫助。
編輯:A return
在proc中將從外部方法返回,而不是從塊中的匿名方法返回。你也許可以設置一個標誌,你可以在bar
檢查,看它是否過早返回:
bar_finished = false
def bar(&block)
proc = Proc.new &block
l.call
bar_finished = true
end
然後,如果return
是傳遞給bar
塊,bar_finished
仍將是假的。不知道是否添加像這樣的非局部變量是一個選項,但如果是這樣,您可以跟蹤塊返回,並拋出任何異常,如果它發生。
雖然你的回答很有洞察力,但它並不回答我的問題。在我的問題中,有一個要求是不改變`bar`外的其他任何東西。你已經發布了一個將`foo`改爲`foo []`的答案。你有隻改變`bar`的解決方案嗎? – pts 2010-12-01 16:20:54
如果您想在yield
之後完成某些「清理」代碼,那麼您可能需要使用begin
,然後使用ensure
。
我很好奇,你爲什麼會想要做這樣的事情? – Chubas 2010-12-01 15:47:39
我想在Ruby 1.8中模擬`Fiber`,`Fiber.new {...}`不支持`return` - 所以仿真也不能支持它。順便說一下,我已經放棄了仿真(都是用`callcc`和`Thread`),因爲我可以寫它,所以它不會泄漏內存。 – pts 2010-12-06 09:17:17