Próbuję lepiej zrozumieć, jak moduły się rozszerzają i wzajemnie uwzględniają.Ruby: moduły rozszerzające/zawierające moduły
Say mam moduł :
module A
def learned_from_A
true
end
end
A.instance_methods # [:learned_from_A]
mieszam swój worek sztuczek w B:
module B
extend A
end
B.learned_from_A # true
ja naiwnie próba nadania C wszystkiemu B ma :
module C
extend B
end
C.learned_from_A # NoMethodError
Myślę, że owinąłem to. Gdy B rozciąga kopie metod przykład są związane z B przez B. klasy jednoelementowy:
B.singleton_methods # [:learned_from_A]
Podczas : learned_from_A jest wywoływalny na B, nie jest jednym z B jest przykład sposoby, tak jeśli C rozciąga B, : learned_from_A to nie skopiowany do C.
Jeśli B miał zamiast zawarte, kopie metod przykład byłby już zostały zaliczone własnych metod instancji przez B.
module B
include A
end
B.instance_methods # [:learned_from_A]
Następnie C może rozciągać B, i wszystkie sposoby przykład przez B (włącznie : learned_from_A) będą skopiowane i związany C.
module C
extend B
end
C.singleton_methods # [:learned_from_A]
Aby : learned_from_A wywoływalny zarówno BiC, B może rozciągać i obejmują .
module B
include A
extend A
end
B.instance_methods # [:learned_from_A]
B.singleton_methods # [:learned_from_A]
module C
extend B
end
C.instance_methods # []
C.singleton_methods # [:learned_from_A]
bardziej realistycznie, jeśli chcę metody „s być wpłacone na B, a dla B zdefiniować inną metodę własnych, i móc mieszać cały repertuar do C, nie mogę tego zrobić:
module B
extend A
include A
def self.buzz
true
end
end
module C
extend B
end
B może udostępniać tylko swoje metody instancji, a nie pojedyncze metody. Tak, aby metodę zarówno wpłacone na B i udostępniania do innych obiektów, musi być zdefiniowana jako metody instancji i przedłużony do B samego:
module B
extend A
include A
extend self
def buzz
true
end
end
module C
extend B
end
Było sporo prób i błąd w łączeniu tego wszystkiego. Czy to dokładny sposób patrzenia na to, co się dzieje?
Czy istnieje sposób na uproszczenie pytania? Nawet jeśli miałbyś to wyjaśnić, z różnymi debugowanymi scenariuszami. – onebree
Myślę, że możesz pomylić zmianę zakresu jaźni, gdy rozszerzasz A wewnątrz B, a następnie spodziewasz się, że C będzie miał A. Zmieniasz zakres. Istnieje również #prepend, który można wywołać. Aby zobaczyć, jak zmieniają się te zakresy, wywołaj metodę $ antenowe w klasie. –
Wygląda na to, że chcesz zadzwonić zarówno do mamy, jak i córki o tej samej nazwie: P –