2016-04-22 8 views
2

Während lange Sicht zu erkennen, ich prepend ausländischen Klassen mit meiner anonymen Module (die im laufenden Betrieb erstellt werden.)Wie meine anonymen Module in Vorfahren einiger Klasse

An einem gewissen Punkt eine Instanz beliebigen Klasse gegeben, Ich muss meine anonymen Module, prepended zu ihm auflisten. Leider Module#new, im Gegensatz zu Class#new, keinen parent Parameter (in anderen Worten, sie können nicht alle einen gleichen gemeinsamen Dummy Elternteil haben, dass ich aus allen ancestors zu Sieb meine Module verwenden könnte.) Akzeptiert

ich konnte Definieren Sie eine spezifische my_litmus_dummy_method auf jedem meiner anonymen Module und überprüfen Sie es während ancestors.select, aber das ist hässlich.

konnte ich include DummyLitmusModule in jedem meiner anonymen Module und prüfen, ob es während ancestors.select ein Vorfahre zu sein, aber das ist entweder hässlich.

Also, meine Frage ist: ist es eine elegante Art und Weise zu Marke meine anonymen Module, so dass später ich sie leicht aus aller Module Liste Sieb könnte?


UPD Codebeispiel

def patch_class klazz 
    klazz.send :prepend, Module.new { define_method(:my_method) {} } 
end 

... 

# load list of classes from somewhere and patch them 
classes = my_parse_yaml('config.yml') 
classes.each do |c| 
    patch_class c 
end 

... 

# somewhere in other place 
instance.patches # ⇐ I want to implement this 

An dieser Stelle möchte ich brauche^W wissen, welche Methoden gepatcht wurden. Ich bin ein wenig neu implementiert alias_method_chain von Rails und ich möchte die "Usages" zu meiner Schnittstelle Benutzer melden.

+0

nicht ganz klar zu mir (vor allem über die 'my_litmus ...' Methode oder 'DummyLitmusModule'):

class Module attr_reader :mods_prepended alias :old_prepend :prepend def prepend(*mods) @mods_prepended =|| {} (@mods_prepended[self] =|| []).concat(mods) end old_prepend(*mods) end class C def patches Module.mods_prepended[self.class] end end 

Dann wird die gewünschte Information gegeben. Ist Ihr Punkt, dass (i) Sie vorgelagerte Module von eingeschlossenen unterscheiden wollen und (ii) Sie sich nur für die anonymen, nicht die genannten interessieren? – sawa

+0

Nicht sicher, aber vielleicht [this] (http://stackoverflow.com/questions/34484006) ist verwandt. – sawa

+1

Warum geben Sie Ihrem anonymen Modul keinen Namen? – Aetherus

Antwort

0

Speichern Sie Ihre anonymen Module irgendwo und dann werden Sie in der Lage sein, sie zu finden:

patches = [Module.new] # some other module 
c = Class.new 
m = Module.new 
c.prepend m 
patches << m 

instance = c.new 
used_patches = patches.select{|p| instance.is_a? p} 
+1

Ja, globale Variablen, liebe es. – mudasobwa

+0

@mudasobwa da jede benannte Klasse/Modul ist in der Tat eine globale Variable - das kann nicht so schlecht sein – Vasfed

1

Was Module#prepend über Patching?

C.new.patches 
+0

Ich habe darüber nachgedacht. Das sieht auf jeden Fall gut aus, aber ich habe Angst davor, 'Module # prepend' zu patchen :) Das ist eine irrationale Angst, die Anfang der 90er Jahre aufkam. Damals wurde es populär, in einigen C/C++ Bibliotheken '# A B zu definieren ', um schnell das gewünschte Ergebnis zu erzielen. Ich vertraue mir selbst, aber in der Produktion soll ich Wale und Turtle intakt halten. – mudasobwa

+0

Ein weiterer Fehler ist, dass es mir gut geht, da 'instance # patches' zeitaufwendig sind, aber ich lehne es ab, Strafen zu generischen Methoden hinzuzufügen. Wie auch immer, Upvoted, da es hier die beste Antwort ist. Nicht als korrekt markiert, weil ich immer noch hoffe, dass es eine Magie geben könnte, die wir alle noch immer vermissen. – mudasobwa

+0

Das Subclassing-Modul klingt vielversprechend: Selbst dieser Alias-Mist wäre verschwunden. Vielleicht das. Ich werde es in meinen Tests versuchen und berichten, danke, Cary! – mudasobwa