Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 606
Amaynut Avatar asked Aug 15 '14 06:08

Amaynut


People also ask

Can you define a method within a method in Ruby?

There's no reason to define a method using def from within a method. You could always move the same inner def construct out of the outer def and end up with the same method. Additionally, defining methods dynamically has a cost. Ruby caches the memory locations of methods, which improves performance.

How do you call a module method in Ruby?

As with class methods, you call a module method by preceding its name with the module's name and a period, and you reference a constant using the module name and two colons.

How do you access a module method in Ruby?

A user cannot access instance method directly with the use of the dot operator as he cannot make the instance of the module. To access the instance method defined inside the module, the user has to include the module inside a class and then use the class instance to access that method.

How do you define a module in Ruby?

To define a module, use the module keyword, give it a name and then finish with an end . The module name follows the same rules as class names. The name is a constant and should start with a capital letter. If the module is two words it should be camel case (e.g MyModule).


1 Answers

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.

like image 121
Chris Heald Avatar answered Oct 09 '22 13:10

Chris Heald