I'm spending today learning Ruby from a Python perspective. One thing I have completely failed to grapple with is an equivalent of decorators. To pare things down I'm trying to replicate a trivial Python decorator:
#! /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)
Running this gives me:
I am going to square 5
25.0
So, I want to create a function square(x), but decorate it so it alerts me as to what it's going to square before it does it. Let's get rid of the sugar to make it more basic:
...
def square(x):
print math.pow(x, 2)
square = document(square)
...
So, how do I replicate this in Ruby? Here's my first attempt:
#! /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)
Running this generates:
./ruby_decorate.rb:8:in `document': wrong number of arguments (0 for 1) (ArgumentError)
from ./ruby_decorate.rb:15:in `<main>'
Which I guess is because parentheses aren't mandatory and it's taking my return wrap as an attempt to return wrap(). I know of no way to refer to a function without calling it.
I've tried various other things, but nothing gets me far.