In der obersten Ebene fügt def
eine private Methode zu Object
hinzu.
kann ich drei Möglichkeiten denken, die Top-Level-Funktion zu erhalten:
(1) Verwenden Sie send
die private Methode auf Object
selbst (funktioniert nur zu berufen, wenn das Verfahren nicht ein Mutator ist seit Object
das sein wird, Empfänger)
Object.send(:fn)
(2) Holen Sie sich ein Method
Instanz der obersten Ebene Verfahren und binden Sie es an die Instanz, die Sie es aufrufen möchten auf:
class Bar
def fn
Object.instance_method(:fn).bind(self).call
end
end
(3) Verwenden Sie super
(nimmt keine Superklassen von Bar
unter Object
die Funktion neu zu definieren)
class Bar
def fn
super
end
end
UPDATE:
Seit Lösung (2) ist die bevorzugte ein (meiner Meinung nach) wir können versuchen, die Syntax durch die Definition eine Hilfsmethode auf Object
super_method
genannt zu verbessern:
class Object
def super_method(base, meth, *args, &block)
if !self.kind_of?(base)
raise ArgumentError, "#{base} is not a superclass of #{self}"
end
base.instance_method(meth).bind(self).call(*args, &block)
end
end
Verwenden Sie wie folgt aus:
class Bar
def fn
super_method Object, :fn
end
end
Wo das erste Argument super_method
muss eine gültige übergeordnete Klasse von Bar
sein, das zweite Argument der Methode, die Sie aufrufen möchten, und alle verbleibenden Argumente (falls vorhanden) entlang als Parameter übergeben zu der ausgewählten Methode.
Ich wusste nicht, dass globale Methoden tatsächlich zum Objekt hinzugefügt werden. Bedeutet dies, dass mein Alias-Ansatz, wie Ihr Super-Ansatz auch auch brechen wird, wenn Bar eine Superklasse hat, die auch Fn definiert? –
@yngvedh, genau. Es wird auf die gleiche Weise brechen. Der allgemeinste Ansatz IMO ist die Verwendung der zweiten Lösung. – horseyguy
@banister, und es gibt keinen anderen Weg, das zu erreichen? Ich denke an etwas, das mehr syntaktisch ansprechend ist, wie zB C++'s Object :: fn. –