加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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>

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读