Вызов метода, определенного в модуле, из переопределенного метода в классе, включающем этот модуль - PullRequest
0 голосов
/ 06 июня 2019

Можно ли вызвать метод, определенный в модуле, если этот метод был переопределен в классе.

Class A
 include bmodule
 def greeting
  super if some_condition_is_true
 end
end

module bmodule
  included do
    has_many :greeters
    def greeting
     puts 'hi'
    end
  end
end

A.new.greeting нужно нажать на приветствие bmodule, если some_condition_is_true имеет значение true

Я попытался добавить и включить модуль, он не работал. Возможно ли это сделать?

Ответы [ 4 ]

1 голос
/ 06 июня 2019

Вы должны сохранить оригинальный метод, прежде чем переопределить его:

Class A
  include bmodule

  alias_method :original_greeting, :greeting

  def greeting
    original_greeting if some_condition_is_true
  end
end

Это пример документа https://apidock.com/ruby/Module/alias_method

0 голосов
/ 06 июня 2019

Да, вы можете сделать это, и вы почти правильно поняли.Просто 1) Прописать Bmodule, чтобы рубин не кричал на вас, 2) строчные class при определении A, 3) включать ActiveSupport :: Concern, если вы используете included, и 4) убрать метод приветствиявключенного блока.Включенный блок предназначен для запуска вещей на уровне класса, и определения метода экземпляра не должны быть внутри него.

module Bmodule
  extend ActiveSupport::Concern

  included do
    has_many :greeters
  end

  def greeting
    puts 'hi'
  end
end

class A
  include Bmodule
  def greeting
    super if some_condition_is_true
  end
end

A.new.greeting
0 голосов
/ 06 июня 2019

Вы можете использовать метод Метод # super_method , который обеспечивает большую гибкость.

module M1
  def meth(arg)
    yield arg
  end
end

module M2
  def meth(arg)
    yield arg
  end
end

class C
  include M1
  include M2

  def meth(arg)
    yield arg
  end

  def test(cond, &block)
    case cond
    when :C
      meth(cond, &block)
    when :M2
      method(:meth).super_method.call(cond, &block)
    when :M1
      (method(:meth).super_method).super_method.call(cond, &block)
    end
  end      
end

C.ancestors
  #=> [C, M2, M1, Object, Kernel, BasicObject]

c = C.new
c.test(:C)  { |m| "meth is from #{m}" }
  #=> "meth is from C" 
c.test(:M2) { |m| "meth is from #{m}" }
  #=> "meth is from M2" 
c.test(:M1) { |m| "meth is from #{m}" }
  #=> "meth is from M1" 

Если по какой-то причине вы хотели использовать prepend вместо include, C.ancesorsбудет выглядеть следующим образом:

class C
  prepend M1
  prepend M2
end

C.ancestors
  #=> [M2, M1, C, Object, Kernel, BasicObject] 

, поэтому вы просто измените test соответственно.

0 голосов
/ 06 июня 2019
module B
  def x
    1
  end
end

class A
  include B
  def x
    super + 1
  end
end

puts A.new.x
# => 2

Блок included do с Rails относится к , поэтому вы можете вызывать методы класса на базе. Поэтому я не думаю, что вам нужно использовать это в этом случае.

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