使用相同的元类调用时,bind中的Singleton方法错误

时间:2012-01-19 19:31:09

标签: ruby metaprogramming singleton-methods

我正在为this question的{{3}}选择的解决方案或多或少地编写方面代码,如下所示:

class Module
  def add_logging klass, *method_names
    method_names.each do |method_name|
      original_method = instance_method method_name
      define_method method_name do |*args, &blk|
        log.debug("#{klass}.#{method_name} called")
        original_method.bind(klass).call(*args, &blk)
      end
    end
  end
end

另一篇文章中的解决方案不需要klass参数,但它只适用于实例方法,而我希望像这样调用我的代码:

module MyModule
  def MyModule.module_method
    p "hello"
  end
  class << self
    add_logging self, :module_method1
  end
end

不幸的是,当我运行此代码时,我得到in 'bind': singleton method called for a different object (TypeError)。看到我在self块的上下文中传递class << self,我不明白为什么上面代码中的绑定调用认为它没有绑定到完全相同的元类。

1 个答案:

答案 0 :(得分:2)

这应该适合你:

class Module
  def add_logging(*method_names)
    method_names.each do |method_name|
      original_method = method(method_name).unbind
      define_singleton_method(method_name) do |*args, &blk|
        puts "#{self}.#{method_name} called"
        original_method.bind(self).call(*args, &blk)
      end
    end
  end
end

# class method example
module MyModule
  def self.module_method1
    puts "hello"
  end

  add_logging :module_method1
end

MyModule.module_method1

# output:
#
# MyModule.module_method1 called
# hello