Цей "ідіоматичний блок" є основною частиною повсякденного Ruby і часто висвітлюється в книгах та навчальних посібниках. Інформаційний розділ рубіна містить посилання на корисні [онлайн] навчальних ресурси.
Ідіоматичним способом є використання блоку:
def x(z)
yield z
end
x(3) {|y| y*y}
Або, можливо, перетворений на Proc ; тут я показую, що "блок", перетворений у Proc неявно за допомогою &block
, - це просто ще одне "викликається" значення:
def x(z, &block)
callback = block
callback.call(z)
end
x(4) {|y| y * y}
(Використовуйте лише наведену форму, щоб зберегти block-now-Proc для подальшого використання або в інших особливих випадках, оскільки це додає накладних та синтаксичних шумів.)
Однак лямбду можна використовувати так само легко (але це не ідіоматично):
def x(z,fn)
fn.call(z)
end
x(5, lambda {|y| y * y})
Хоча вищезазначені підходи можуть обертати "виклик методу", оскільки вони створюють закриття, зв'язані методи також можна розглядати як першокласні об'єкти, що викликаються:
class A
def b(z)
z*z
end
end
callable = A.new.method(:b)
callable.call(6)
def x(z,fn)
fn.call(z)
end
x(7, callable)
Крім того, іноді корисно використовувати #send
метод (зокрема, якщо метод відомий за назвою). Тут він зберігає проміжний об'єкт Method, який був створений в останньому прикладі; Ruby - це система передачі повідомлень:
def x(z, a):
a.__send__(:b, z)
end
x(8, A.new)
Щасливого кодування!