Вызов метода класса собственного класса

Мне нужно переопределить метод класса для некоторых экземпляров класса

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"

Есть ли способ вызвать переопределенный метод без явного получения собственного класса?

2 ответа

С момента реализации 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 вернуть собственный класс.

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

      def class
        eigen_class
      end
    end
  end
end

Вообще, не стоит переопределять методы, определенные в Object, как #class так как это может иметь непредвиденные последствия.

Вы назначаете этот метод в неправильном контексте. Вот исправление:

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

Это связывает метод с классом Foo, а не с собственным классом этого конкретного экземпляра.

Другие вопросы по тегам