我的教授在课堂上展示了以下示例,它的工作非常精细且打印
def printv(g)
puts g.call("Fred")
puts g.call("Amber")
end
printv(method(:hello))
>>hello Fred
hello Amber
但是当我尝试在我的irb / RubyMine上运行它时,它显示未定义的方法错误。我正在尝试他在课堂上展示的确切代码。我错过了什么?
谢谢!
答案 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