Я трачу сегодня на изучение Ruby с точки зрения Python. Одна вещь, с которой я полностью не справился, - это эквивалент декораторов. Чтобы избавиться от вещей, я пытаюсь воспроизвести тривиальный декоратор Python:
#! /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)
Выполнение этого дает мне:
I am going to square 5 25.0
Итак, я хочу создать функцию square (x), но украсить ее, чтобы она предупреждала меня о том, что она собирается квадратировать, прежде чем она это сделает. Позвольте избавиться от сахара, чтобы сделать его более простым:
...
def square(x):
print math.pow(x, 2)
square = document(square)
...
Итак, как я могу воспроизвести это в Ruby? Вот моя первая попытка:
#! /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)
Запуск этого процесса генерирует:
./ruby_decorate.rb:8:in `document': wrong number of arguments (0 for 1) (ArgumentError)
from ./ruby_decorate.rb:15:in `'
Я думаю, это потому, что скобки не являются обязательными, и он берет мой "обратный перенос" как попытку "return wrap()". Я не знаю, как обращаться к функции, не вызывая ее.
Я пробовал разные вещи, но меня ничего не дало.