Если вы посмотрите на код для printv
, вы увидите, что g
должен будет предоставить метод call
.В Ruby есть несколько классов, которые предоставляют метод call
по умолчанию, среди них procs и lambdas:
hello = lambda { |name| puts "Hello, #{name}" }
printv(hello) # prints: Hello, Fred and Hello, Amber
Здесь hello
- это переменная, хранящая лямбда, поэтому вам не нужен символ(:hello
) для ссылки на него.
Теперь давайте рассмотрим метод method
.Согласно документам он «[l] вызывает именованный метод в качестве получателя в obj, возвращая объект метода (или вызывая NameError)».Его подпись - «obj.method (sym) → метод», что означает, что она принимает аргумент символа и возвращает объект метода .Если вы сейчас вызовете method(:hello)
, вы получите NameError
, упомянутый в документации, поскольку в настоящее время нет метода с именем "hello".Как только вы определите один из них, все будет работать:
def hello(name)
"Hello, #{name}"
end
method(:hello) #=> #<Method: Object#hello>
>> printv(method(:hello)) # works as expected
Это также объясняет, почему вызов printv(method("hello")
, который вы упоминаете в своем комментарии к другому ответу, терпит неудачу: method
пытается извлечь методобъект, но терпит неудачу, если нет метода с таким именем (строка в качестве аргумента, кажется, работает кстати, кажется, method
интернирует свой аргумент на всякий случай).