Неопределенная ошибка метода в Ruby - PullRequest
0 голосов
/ 18 сентября 2011

Следующий пример был показан моим преподавателем в классе, и он отлично работал и напечатал

def printv(g)
  puts g.call("Fred")
  puts g.call("Amber")
end

printv(method(:hello))

>>hello Fred

  hello Amber

но когда я пытаюсь запустить его на моем irb / RubyMine, он показывает неопределенную ошибку метода. Я пытаюсь точный код, что он показал в классе. Чего мне не хватает?

Спасибо!

Ответы [ 2 ]

4 голосов
/ 18 сентября 2011

Если вы посмотрите на код для 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 интернирует свой аргумент на всякий случай).

3 голосов
/ 18 сентября 2011

Вам также необходимо определить метод "привет".

def printv(g)
  puts g.call("Fred")
  puts g.call("Amber")
end

def hello(s)
   "hello #{s}"
end 

printv(method(:hello))

>>hello Fred

  hello Amber 
...