Undefined method error in Ruby
The following example was showed by my professor in class and it worked perfectly fine and printed
def printv(g)
puts g.call("Fred")
puts g.call("Amber")
end
printv(method(:hello))
>>hello Fred
hello Amber
but when I am trying to run it on my irb/RubyMine its showing undefined method error. I am trying the 开发者_如何学运维exact code what he showed in class. What am I missing?
Thanks!
If you look at the code for printv
, you'll see that g
will have to provide a call
method. There are several classes in Ruby that provide a call
method by default, amongst them procs and lambdas:
hello = lambda { |name| puts "Hello, #{name}" }
printv(hello) # prints: Hello, Fred and Hello, Amber
Here hello
is a variable storing a lambda, so you don't need a symbol (:hello
) to reference it.
Now let's look at the method method
. According to the docs it "[l]ooks up the named method as a receiver in obj, returning a Method object (or raising NameError)". It's signature is "obj.method(sym) → method", meaning it takes a symbol argument and returns a method object. If you call method(:hello)
now, you'll get the NameError
mentioned in the docs, since there is currently no method named "hello". As soon as you define one, things will work though:
def hello(name)
"Hello, #{name}"
end
method(:hello) #=> #<Method: Object#hello>
>> printv(method(:hello)) # works as expected
This also explains why the call printv(method("hello")
that you mention in your comment on the other answer fails: method
tries to extract a method object, but fails if there is no method by that name (a string as argument seems to work by the way, seems like method
interns its argument just in case).
You'll need to define the method "hello" as well.
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
精彩评论