0

下面的例子是我的教授在课堂上展示的,效果很好,打印出来了

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

printv(method(:hello))

>>hello Fred

  hello Amber

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

谢谢!

4

2 回答 2

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(: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实习生它的论点以防万一)。

于 2011-09-17T22:17:02.193 回答
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 
于 2011-09-17T20:26:16.517 回答