调用本征类的类方法

时间:2012-11-19 15:27:12

标签: ruby eigenclass

我需要覆盖类

的某些实例的类方法
class Foo
  def eigen_class
    class << self
      self
    end
  end

  def self.foo
    "original foo"
  end

  def override_foo
    class << self
      def self.foo
        "overridden foo"
      end
    end
  end
end

foo = Foo.new
foo.override_foo
foo.class.foo # => "original foo"
foo.eigen_class.foo # => "overridden foo"

foo2 = Foo.new
foo2.eigen_class.foo # => "original foo"

有没有办法在没有显式获取eigenclass的情况下调用重写方法?

2 个答案:

答案 0 :(得分:0)

您将该方法分配给错误的上下文。这是一个修复:

class << foo.class
  def foo
    "foo"
  end
end

这将方法固定到Foo类,而不是该特定实例的本征类。

答案 1 :(得分:0)

由于foo的实现可能因实例而异,我建议只使用常规方法(即实例方法,而不是类方法)。您可以使用模块轻松完成此操作,保持所有覆盖都是自包含的。

module FooOverrides
  def foo
    "overridden foo"
  end
end

class Foo
  def foo
    "original foo"
  end

  def override_foo
    self.extend(FooOverrides)
  end
end

foo = Foo.new
foo.override_foo
foo.foo # => "overridden foo"

foo2 = Foo.new
foo2.foo # => "original foo"

或者,如果您真的想要调用foo.class.foo,则可以覆盖#class以返回eigen_class。

class Foo
  def override_foo
    class << self
      def self.foo
        "overridden foo"
      end

      def class
        eigen_class
      end
    end
  end
end

一般来说,覆盖像#class这样的对象上定义的方法并不好,因为它可能会产生意想不到的后果。