Metaprogramowanie: inherited, dostęp do singleton methods

Mam małą zagwozdkę:

class A def self.inherited(klass) puts klass.singleton_methods.inspect # klass.supported? # pluje, że nie ma metody end end

class B < A def self.supported? true end end
w wyniku uruchomienia tego programu otrzymuję:

["inherited"]

Że się grzecznie zapytam: WTF?

Nie wkleiłeś kodu, który wyrzuca output :]

Jak nie, jest w hooku inherited.
Był bład. Tam miało być self.inherited

Problem polega generalniena tym, że chce w klasie rodzicu wywołac w momencie po zdefiniowaniu klasy dziecka metodę “statyczną” tejże klasy, odebrać wartość i odpowiednio te klasę zakwalifikować (wsadzić w odpowiednie miejsce Hasha)

Dokumentacja:
http://ruby-doc.org/core/classes/Class.html#M002785

Na Experts Exchange (triala założyłem na chwilę :P) napisali, że się nie da w ten sposób, bo inherited wywoływane jest natychmiast po ceklaracji

class B < A

[code=ruby]class A
def self.metoda
“jestem rodzicem”
end

def self.inherited(klass)
puts klass.metoda
end
end

class B < A
end[/code]

chodziło o to, że metoda “metoda” miała być deklarowana w klasie B :slight_smile:

Chciałem już napisać, że to proste, bo wystarczy zrobić taką metodę w klasie A i nadpisać ją w klasie B, ale nie bardzo to wyjdzie, bo w “inherited” w klasie B nie ma jeszcze metod.

[code=ruby] class A
def self.metoda
puts “Abstract method, implement me.”
end

def self.inherited(klass)
  puts klass.inspect
  klass.metoda
end

end

class B < A
def self.metoda
puts “Klasa B”
end
end

#=> B
#=> Abstract method, implement me.
B.metoda
#=> Klasa B[/code]

No tak, callback jest wywoływany od razu, zanim ciało klasy B się wykona. savos opisz co chcesz osiągnąć, może istnieje inne rozwiązanie.

Cześć,

a mi się wydaje, że cała koncepcja tego rozwiązania jest zła…

Siłą rzeczy klasa B zależy od swojego rodzica i wprowadzanie dodatkowej zależności w drugą stronę jest błędem.

Ja bym to rozwiązał w ten sposób:

[code=ruby]# Możesz podzielić ten moduł na ClassMethods i InstanceMethods oraz dorzucić

hook included, aby dołączał metody z InstanceMethods i ClassMethods

module A
def self.classification
@classification ||= {}
end

def setup_a(options)
A.classification[options.delete(:belongs_to)] = self
end
end

class B
extend A

setup_a :belongs_to => :group_a # możesz tu również umieścić blok, które “wyliczy” grupę :wink:
end

puts A.classification[/code]
Wypisuje:

group_aB