下面的例子是我的教授在课堂上展示的,效果很好,打印出来了
def printv(g)
puts g.call("Fred")
puts g.call("Amber")
end
printv(method(:hello))
>>hello Fred
hello Amber
但是当我试图在我的 irb/RubyMine 上运行它时,它显示未定义的方法错误。我正在尝试他在课堂上展示的确切代码。我错过了什么?
谢谢!
如果您查看 的代码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
实习生它的论点以防万一)。
您还需要定义方法“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