0

我需要为类的某些实例覆盖类方法

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"

有没有办法在不显式获取特征类的情况下调用覆盖方法?

4

2 回答 2

0

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

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

这将方法绑定到 Foo 类,而不是该特定实例的 eigenclass。

于 2012-11-19T16:36:40.290 回答
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因为它可能会产生意想不到的后果。

于 2012-11-19T18:37:04.973 回答