Ruby中未定义的方法错误

时间:2011-09-17 20:05:46

标签: ruby irb rubymine

我的教授在课堂上展示了以下示例,它的工作非常精细且打印

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

printv(method(:hello))

>>hello Fred

  hello Amber

但是当我尝试在我的irb / RubyMine上运行它时,它显示未定义的方法错误。我正在尝试他在课堂上展示的确切代码。我错过了什么?

谢谢!

2 个答案:

答案 0 :(得分:4)

如果查看printv的代码,您会发现g必须提供call方法。 Ruby中有几个类默认提供call方法,其中包括procs和lambdas:

hello = lambda { |name| puts "Hello, #{name}" }
printv(hello) # prints: Hello, Fred and Hello, Amber

这里hello是一个存储lambda的变量,所以你不需要一个符号(:hello)来引用它。

现在让我们看看方法method。根据文档,它“[l]将命名方法作为obj中的接收者,返回一个Method对象(或引发NameError)”。它的签名是“obj.method(sym)→method”,意思是它采用符号参数并返回method object。如果您现在致电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尝试提取方法对象,但如果没有该方法的方法则失败(a字符串作为参数似乎是顺便说一句,似乎method实例化其论证。)

答案 1 :(得分:3)

您还需要定义方法“hello”。

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