2016-01-12 2 views
6

ich dynamisch die Klasse bestimmen, die aktuelle Methode in wurde möchte definiertWie kann man die Klasse bestimmen, in der eine Methode definiert wurde?

Hier ist ein statisches Beispiel dafür, was ich versuche zu tun. Die

class A 
    def foo 
    puts "I was defined in A" 
    end 
end 

class B < A 
    def foo 
    puts "I was defined in B" 
    super 
    end 
end 

A.new.foo 
# I was defined in A 

B.new.foo 
# I was defined in B 
# I was defined in A <- this is the tricky one 

Wie kann ich ersetzen A und B in Saiten oben mit einem dynamischen Ausdruck?

Anscheinend funktioniert #{self.class} nicht. (Es wäre I was defined in B zweimal für B drucken)

Ich vermute, dass die Antwort ist „Sie können nicht“, aber vielleicht bin ich etwas übersehen.

+1

Der Schlüssel zu all it :) – ndn

+1

@ndn ich für '__class__' gehofft wurde, aber es ist nicht vorhanden . – Stefan

+1

Warum müssen Sie das wissen? –

Antwort

4

Was ist damit?

Korrigiert folgenden Vorschlag von WandMaker.

+1

Ich habe diese Antwort gewählt, weil 'Module.nesting' das gezeigte Problem löst und weil sawa zuerst gepostet hat. Es löst jedoch nicht das eigentliche Problem, das ich angesprochen habe, also habe ich eine [Follow-up-Frage] gestellt (http://stackoverflow.com/q/34745608/477037). – Stefan

3

Sie könnten verwenden.

Beachten Sie jedoch, dass dies funktioniert rein lexikalisch, die gleiche Art und Weise Konstanten Auflösung arbeitet, so wird es nicht schneiden, wenn Sie dynamischere Bedürfnisse haben:

Foo = Class.new do 
    def foo 
    Module.nesting 
    end 
end 

Foo.new.foo # => [] 
+0

Bei verschachtelten Modulen kann es keine richtige Antwort geben. Kommt darauf an, was OP benötigt - Klassenname oder Modulname. –

+3

Versuchen Sie, 'Klasse A' innerhalb eines' Modul C' zu definieren - es wird sagen, Methode wurde in 'C' definiert, wenn Sie' Module.nesting.last' verwenden. Möglicherweise muss man 'Module.nesting.first' verwenden –

3

ich dieses nagende Gefühl, dass, wenn Sie könnten würde dies die objektorientierte Verkapselung verletzen, obwohl ich nicht genau sagen kann, warum. Es sollte also nicht überraschen, dass es schwer ist.

Ich kann eine Art und Weise sehen, wenn Sie die Methode zur Modifizierung Definitionen offen sind:

class A 
    this = self 
    define_method(:foo) do 
    puts "I was defined in #{this}" 
    end 
end 

class B < A 
    this = self 
    define_method(:foo) do 
    puts "I was defined in #{this}" 
    super() 
    end 
end 

A.new.foo 
# I was defined in A 

B.new.foo 
# I was defined in B 
# I was defined in A 
+0

Schön, aber immer noch nicht in einigen dynamischen Fällen arbeiten. So definieren Sie eine Methode für eine Klasse außerhalb der Klasse. (: – ndn

+0

) Ich verstehe, dass 'Module.nesting' zu den wenigen Methoden/Schlüsselwörtern gehört, die lexikalisch arbeiten (dh, das Verhalten hängt von ihrer Position im Quellcode ab) und daher nicht direkt von Methode zu Methode weitergegeben werden kann als "binding", "__FILE__", "__LINE__", "__dir__", "Module.nesting" und vielleicht noch einige mehr. – sawa

+1

@sawa '__method__' ist ein anderer. – Stefan

Verwandte Themen