[英]Passing a block to a dynamically created method
我正在創建一個擴展ActiveRecord模型功能的模塊。
這是我的初始設置。
我的課:
class MyClass < ActiveRecord::Base
is_my_modiable
end
和模塊:
module MyMod
def self.is_my_modiable
class_eval do
def new_method
self.mod = true
self.save!
end
end
end
end
ActiveRecord::Base(extend,MyMod)
我現在要做的是通過傳入一個塊來擴展new_method
的功能。 像這樣的東西:
class MyClass < ActiveRecord::Base
is_my_modiable do
self.something_special
end
end
module MyMod
def self.is_my_modiable
class_eval do
def new_method
yield if block_given?
self.mod = true
self.save!
end
end
end
end
這不起作用,這是有道理的。 在class_eval中,new_method沒有被執行,只是被定義,因此在實際調用該方法之前,yield語句不會被執行。
我試圖將塊分配給class_eval中的類變量,然后在方法中調用該類變量,但是在所有is_my_modiable模型上調用該塊,即使它們沒有將塊傳遞給方法。
我可能會覆蓋該方法以獲得相同的效果,但我希望有一種更優雅的方式。
如果我理解正確,你可以通過將傳遞的塊保存到類對象上的實例變量然后在實例方法中進行評估來解決這個問題。
bl.call
不會在這里執行,因為它將在原始上下文(類的)中執行,並且您需要在當前實例的范圍內執行它。
module MyMod
def is_my_modiable(&block)
class_eval do
@stored_block = block # back up block
def new_method
bl = self.class.instance_variable_get(:@stored_block) # get from class and execute
instance_eval(&bl) if bl
self.mod = true
self.save!
end
end
end
end
class MyClass
extend MyMod
is_my_modiable do
puts "in my modiable block"
self.something_special
end
def something_special
puts "in something special"
end
attr_accessor :mod
def save!; end
end
MyClass.new.new_method
# >> in my modiable block
# >> in something special
您可以通過將塊指定為方法參數來執行此操作:
module MyMod
def self.is_my_modiable
class_eval do
def new_method(&block)
block.call if block
self.mod = true
self.save!
end
end
end
end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.