Ruby:如何挂钩类方法
发布时间:2020-12-17 02:15:27 所属栏目:百科 来源:网络整理
导读:来自: http://cheind.blogspot.com/2008/12/method-hooks-in-ruby.html 我有 # Contains methods to hook method callsmodule FollowingHook module ClassMethods private # Hook the provided instance methods so that the block # is executed directly
来自:
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 在另一个位置/文件中,我重新打开User类并挂钩它 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上包含FollowingHook代码,然后调用以下内容,以便它适用于类方法.
Class.send(:include,FollowingHook) class User class << self following :get do |reciever,args| # Your awesome code here end end end 编辑: 这是我完整的工作解决方案,遵循这一建议: # 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,:return => ret ) ret # Forward return value of method end end end end end def self.included(base) base.send(:extend,FollowingHook::ClassMethods) end end class User def self.foo puts "foo" end def bar puts "bar" end end # You can put this in the class << self block if you prefer that the # methods only be available on the User class. Class.send(:include,FollowingHook) class User include FollowingHook following :bar do |receiver,args| puts receiver.inspect end class << self # If you prefer only the User class include FollowingHooks,use the # following instead of including them in Class. # include FollowingHook following :foo do |receiver,args| puts receiver.inspect end end end User.foo #=> # foo # User User.new.bar #=> # bar # #<User:0x338d9d> (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |