Ich verbringe den heutigen Tag damit, Ruby aus der Perspektive von Python zu lernen. Eine Sache, mit der ich mich noch nicht auseinandergesetzt habe, ist die Entsprechung von Dekoratoren. Um die Dinge zu vereinfachen, versuche ich, einen trivialen Python-Dekorator zu replizieren:
#! /usr/bin/env python
import math
def document(f):
def wrap(x):
print "I am going to square", x
f(x)
return wrap
@document
def square(x):
print math.pow(x, 2)
square(5)
Wenn ich das mache, habe ich etwas davon:
I am going to square 5
25.0
Ich möchte also eine Funktion erstellen square(x)
aber schmücken Sie es so aus, dass es mich darauf aufmerksam macht, was es quadrieren wird, bevor es es tut. Lassen wir den Zucker weg, damit es einfacher wird:
...
def square(x):
print math.pow(x, 2)
square = document(square)
...
Wie kann ich dies also in Ruby nachbilden? Hier ist mein erster Versuch:
#! /usr/bin/env ruby
def document(f)
def wrap(x)
puts "I am going to square", x
f(x)
end
return wrap
end
def square(x)
puts x**2
end
square = document(square)
square(5)
Die Ausführung erzeugt dies:
./ruby_decorate.rb:8:in `document': wrong number of arguments (0 for 1) (ArgumentError)
from ./ruby_decorate.rb:15:in `<main>'
Das liegt wohl daran, dass Klammern nicht obligatorisch sind, und es nimmt meine return wrap
als einen Versuch, die return wrap()
. Mir ist keine Möglichkeit bekannt, auf eine Funktion zu verweisen, ohne sie aufzurufen.
Ich habe verschiedene andere Dinge ausprobiert, aber nichts bringt mich weiter.