來源:http://cheind.blogspot.com/2008/12/method-hooks-in-ruby.html紅寶石:如何鉤住類方法
我
# Contains methods to hook method calls
module FollowingHook
module ClassMethods
private
# Hook the provided instance methods so that the block
# is executed directly after the specified methods have
# been invoked.
#
def following(*syms, &block)
syms.each do |sym| # For each symbol
str_id = "__#{sym}__hooked__"
unless private_instance_methods.include?(str_id)
alias_method str_id, sym # Backup original
# method
private str_id # Make backup private
define_method sym do |*args| # Replace method
ret = __send__ str_id, *args # Invoke backup
block.call(self, # Invoke hook
:method => sym,
:args => args,
:return => ret
)
ret # Forward return value of method
end
end
end
end
end
# On inclusion, we extend the receiver by
# the defined class-methods. This is an ruby
# idiom for defining class methods within a module.
def FollowingHook.included(base)
base.extend(ClassMethods)
end
end
然後,我有一個類,像這樣:
class User
def self.get
#class method
end
def name
#instance method
end
end
在另一個位置/文件我重新打開用戶類別和掛鉤它
class User
include FollowingHooks # include the hook module
following :name do |receiver, args|
#do something. This works!!
end
following :get do |reciever, args|
#do something. THIS DOESNT WORK
# Which is to be expected looking at the FollowingHooks module definition.
end
end
掛鉤到任何實例方法的作品。然而,試圖鉤入類方法並沒有做任何事情,我得到了,因爲FollowingHooks模塊沒有實現它。我將如何實現類方法的鉤子?我完全無能爲力。
這不起作用。我在#之後得到「未定義的方法」。這是有道理的,因爲「class << self'會改變爲單例上下文,並且如果以某種方式解決了這個問題,它仍然會影響到在FollowingHook中的」define method「調用,因爲define_method總是定義一個實例方法而不是如果上下文是一個類,我想過使用「define_singleton_method」,但是這也不起作用。 –
2013-03-01 00:46:28
您是否運行了'Class.send(:include,FollowingHook)'?這就是解決了「undefined方法「的問題 – 2013-03-01 15:21:27
一個類只是一個類的實例,所以在一個類的單例中調用'define_method'正確地將這些方法定義爲類方法 – 2013-03-01 15:23:10