Как переписать метод собственного класса в ruby? - PullRequest
0 голосов
/ 26 июня 2018

у меня есть модуль

module A
  class << self
    def is_okay?; false; end
  end
end

и мне нужно переписать is_okay? метод в другом модуле. Модуль B включается в A таким образом

A.send(:include, B)

Я пробовал это

module B
  class << self
    def is_okay?; true; end
  end
end

и тот

module B
  def self.is_okay?; true; end
end

но это не сработало. Как мне этого добиться?

Ответы [ 2 ]

0 голосов
/ 27 июня 2018

Рассмотрим следующее.

module B
  def bi
    "hello from bi"
  end
  def self.bm
    "hello from bm"
  end
end

B.instance_methods(false)
  #=> [:bi]
B.methods(false)
  #=> [:bm]

Обратите внимание, что определение метода модуля (здесь bm) с помощью self. такое же, как определение метода экземпляра для одноэлементного класса модуля.

Теперь создайте модуль A, который включает B.

module A
  def self.am
    "hello from am"
  end
end

A.methods(false)
  #=> [:am]
A.include B

A.instance_methods.include?(:bi)
  #=> true
A.methods.include?(:bm)
  #=> false

Как и ожидалось, bi теперь является методом экземпляра A. include, однако, игнорирует методы модуля, здесь B::bm. Есть ли способ для модульного метода B::m стать модульным методом A? Ответ - нет". По сути, мы хотим

A.singleton_class.include B.singleton_class

но это не работает, потому что B.singleton_class - это класс.

Module # include не дает понять, может ли модуль (возможно, класс) включать класс. Попробуйте, однако, и вы увидите следующее исключение:

TypeError (wrong argument type Class (expected Module))

Если методы модуля модуля M не доступны для другого модуля, который включает M, есть ли причина для модулей иметь методы модуля? Да, предоставить библиотеки методов! Примером является модуль Math . Этот модуль содержит много методов модуля и никаких методов экземпляра. Поэтому при использовании эти методы вызываются на их приемнике Math. Например,

Math.sin(x)
0 голосов
/ 26 июня 2018

Это может или не может работать в вашей ситуации:

module B
  def is_okay?
    true
  end
end

module A

  class << self

    prepend B

    def is_okay?
      false
    end
  end
end

prepend аналогично include, но вставляет себя перед классом, в "нижней части" цепочки предков.

EDIT:

Поскольку вы пояснили в своих комментариях ниже (я бы предложил уточнить ваш первоначальный вопрос), вы можете использовать псевдоним так же, как и любой другой метод.

module A

  class << self
    alias original_is_okay? is_okay?
    def is_okay?
      true
    end

  end
end

Это позволит "перезаписать его, независимо от того, есть ли у вас доступ к нему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...