Amaynut Amaynut - 2 months ago 9
Ruby Question

Defining a method inside a module in ruby (NoMethodError)

I'm learning ruby, I come up on something that I don't understand. I know that modules in ruby are used for namespacing with :: (or .) and mixing with include directive.
The problem comes when I group some methods inside a module, without putting them inside a class.
Here's an example:

module Familiar
#this will not work
def ask_age
return "How old are you?"
end
#this will work
def Familiar::greeting
return "What's up?"
end
end
# this call returns **NoMethodError**
puts(Familiar::ask_age())
# this call works fine
puts(Familiar::greeting())


Why do I need to include the namespace to define the method, I'm already inside the namespace Familiar why do I have to repeat my self and put Familiar::greeting
You can test my example online following this link: http://codepad.org/VUgCVPXN

Answer

The Ruby documentation on Module answers this in its introduction text.

This form:

module Familiar
  def ask_age
    return "How old are you?"
  end
end

defines #ask_age as an instance method on Familiar. However, you can't instantiate Modules, so you can't get to their instance methods directly; you mix them into other classes. Instance methods in modules are more or less unreachable directly.

This form, by comparison:

module Familiar
  def self.ask_age
    return "What's up?"
  end
end

defines ::ask_age as a module function. It is directly callable, and does not appear on included classes when the module is mixed into another class.