2017-07-10 13 views
1

Gibt es eine Möglichkeit, ein Objekt zu erstellen, das Eigenschaften hat und nur mit der Notation eines Funktionsaufrufs aufgerufen werden kann? Etwas, das Pythons __call__ entspricht.Wie kann ich ein Objekt aufrufbar machen?

Zum Beispiel:

obj = ExampleClass.new() 
obj() # call notation 

Alternative Ansätze sind willkommen, ich brauche einen Weg für das aufrufbare „Objekt“ seine eigenen Eigenschaften zu speichern.

Was ich versuche zu tun ist ein abrufbares "Objekt" in einer Variablen zu speichern. Dieses Objekt verfügt über Eigenschaften, die ihm zugeordnet sind, während es gleichzeitig genau wie eine Methode verwendet werden kann. daher

+1

Das ist mir nicht bekannt (und ich kann mir auch keinen großen Anwendungsfall vorstellen). Welchen spezifischen Anwendungsfall versuchen Sie zu lösen? Es könnte einen besseren Ansatz geben. –

+0

"es kann genau wie eine Funktion verwendet werden" - beachten Sie, dass Ruby keine Funktionen hat (die Art, die Sie in, sagen wir, Javascript haben) –

Antwort

1

Wenn Sie bereit sind, um die gewünschte Syntax ein wenig ...

zu ändern
class Foo 
    def call 
    puts 'called' 
    end 
end 

f = Foo.new 
f.() 
# >> called 

Die genaue Syntax, wie in Ihrer Frage ist, in Ruby nicht möglich, da Klammern optional und sind, f() ist das gleiche wie f. Dies ist im Fall eines aufrufbaren Objekts nicht eindeutig. Möchten Sie den Aufruf ausführen oder nur auf das aufrufbare Objekt verweisen? Expliziter Aufruf (mit der Punktsyntax) entfernt die Mehrdeutigkeit.

2

Sie können kein Objekt aufrufbar, so weit machen, wie ich das ist reserviert für Methodenaufrufe wissen, aber man kann es mit ein bisschen ein Hack tun eine alternative Notation:

class ExampleClass 
    def [] 
    :callable 
    end 
end 

Sie Wo jetzt tun können:

example = ExampleClass.new 
example[] 

Dies ähnelt, wie Sie ein Proc anrufen:

proc = Proc.new { :return_value } 
proc[] 
# => :return_value 

Es ist n ot perfekt, aber es wird funktionieren.

Beachten Sie, dass Sie normalerweise eine Menge von diesem Chaos umgehen können, indem Sie Ihre API um diese Einschränkungen herum aufbauen.