Ошибка метода Singleton при связывании при вызове с тем же метаклассом - PullRequest
1 голос
/ 19 января 2012

Я пишу код аспекта, более или менее снятый с выбранного решения для этого вопроса , который выглядит следующим образом:

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 Ответ

2 голосов
/ 20 января 2012

Это должно работать для вас:

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
...