在一個類的正文中,我想通過一個塊來稱爲with
。對於塊的整個生命週期,我想要一個with_value
方法可用。如何製作一個持續一個塊的生命週期的Ruby方法?
否則,塊內的所有內容都應該表現得好像它在塊外面一樣。
下面是一個例子:
class C
extend M
with "some value" do
do_something_complicated
do_something_complicated
do_something_complicated
end
end
我們可以幾乎用得到:
module M
def with(str, &block)
Object.new.tap do |wrapper|
wrapper.define_singleton_method :with_value do # Here's our with_value
str # method.
end
end.instance_eval &block
end
def do_something_complicated # Push a value onto an
(@foo ||= []).push with_value # array.
end
end
,但有一個問題:因爲我們正在評估傳遞給with
的上下文中的塊一個不同的對象,do_something_complicated
不可用。
什麼是正確的方法來解決這個問題?
你可以在'instance_eval'之前包裝'擴展M'。你能說出你的理由嗎?它可以幫助我們提出一個可靠的解決方案。 – Kyle
@Kyle如果你在包裝器上'擴展','do_something_complicated'將推到錯誤的數組(包裝器的'@ foo'而不是'C'的'@ foo'。我正在這樣做一個小的DSL用於包含可組合形式的ActiveRecord對象的一些混亂情況 –