Как разрешить конфликт между модулем ruby ​​и методом mixin

Свойства зависимостей обычно должны считаться общедоступными, доступными или, по крайней мере, доступными для любого вызывающего объекта, имеющего доступ к экземпляру.

Я думаю, что раздел «Вопросы безопасности свойств зависимостей» в приведенной ниже ссылке может помогите понять, почему свойства зависимостей реализованы / зарегистрированы таким образом и более на этом:

http://msdn.microsoft.com/en-us/library/ms753358.aspx

Спасибо

0
задан sawa 18 January 2019 в 08:44
поделиться

2 ответа

Проблема для вас в том, что в Ruby нет множественного наследования; поэтому модули вставляются как предки один над другим и как таковые F#initialize омрачают E#initialize. Как вы обнаружили, к нему легко получить доступ F#initialize, используя super(f); но другому нужен взлом для доступа: мы можем выбрать метод initialize непосредственно из модуля, потому что он является предком; затем привязать его к текущему объекту и запустить его.

def initialize(e, f)
  E.instance_method(:initialize).bind(self).call(e)
  F.instance_method(:initialize).bind(self).call(f) # equivalent to super(f)
end

Однако я не рекомендую это. Если вам нужно запустить несколько инициализаторов, вам лучше использовать композицию, а не наследование (и, надо понимать, include - это наследование).

0
ответ дан Amadan 18 January 2019 в 08:44
поделиться

Для этого вы можете использовать Метод # super_method .

module E
  def initialize(e)
    @e = e
  end
  def e
    @e
  end
end

module F
  def initialize(f)
    @f = f
  end

  def f
    @f
  end
end

class A
  include E
  include F

  def initialize(e, f)
    select_initialize(E).call e
    select_initialize(F).call f
  end

  private

  def select_initialize(mod) 
    self.class.
         ancestors.
         index(mod).
         times.
         reduce(method(:initialize)) { |m,_| m.super_method }
  end
end

puts A.new("E", "F").f
  #=> F
puts A.new("E", "F").e
  #=> E

Примечание:

A.ancestors
  #=> [A, F, E, Object, Kernel, BasicObject] 

См. Также Модуль # предков , Массив # index , Integer # times , Enumerable # Reduce (он же inject), Object # method и Вызов метода # .

E и F могут, конечно, содержать другие методы экземпляров, которые необходимы экземплярам класса.

0
ответ дан Cary Swoveland 18 January 2019 в 08:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: