Свойства зависимостей обычно должны считаться общедоступными, доступными или, по крайней мере, доступными для любого вызывающего объекта, имеющего доступ к экземпляру.
Я думаю, что раздел «Вопросы безопасности свойств зависимостей» в приведенной ниже ссылке может помогите понять, почему свойства зависимостей реализованы / зарегистрированы таким образом и более на этом:
http://msdn.microsoft.com/en-us/library/ms753358.aspx
Спасибо
Проблема для вас в том, что в 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
- это наследование).
Для этого вы можете использовать Метод # 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
могут, конечно, содержать другие методы экземпляров, которые необходимы экземплярам класса.