Search code examples
rubyirbrubymine

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!


Solution

  • 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).