15

In what sort of situation is the code:

module M
   extend self
   def greet
    puts "hello"
   end

end

more beneficial to use over say something like:

module M
   def self.greet
    puts "hello"
   end
end

In the top, one is an instance method being extended, and the latter is just a class method, but when calling either method, you'd have to M.greet , right? I was just curious if anyone could shed some light on when to use one code over the other. Thanks!

joeellis
  • 2,745
  • 7
  • 28
  • 45

3 Answers3

15

The first example is typically a way people achieve the functionality of module_function (when they do not know the existence of this method).

A module_function is both an instance method and a class method. In your second code example the method is just a class method.

horseyguy
  • 29,455
  • 20
  • 103
  • 145
  • Oh, that's a cool method. That way you can select which methods to give the functionality to in case you don't want to give it to all of them. Thanks! – joeellis Jul 29 '10 at 14:44
10

It would be possible to do this with your first example, but not your second:

include M
greet
Adrian
  • 14,931
  • 9
  • 45
  • 70
4

A module can be used as a namespace by writing module methods, and a module's instance methods can be mixed into another object.

The self-extending module concept allows a module to be used in both ways; either as a stand-alone namespace or as a mixin. Consider this module:

module M
  def bar
    puts "bar"
  end
end
class C
  include M
end

It has an instance method and can be mixed in to another object. It does not have a module method and cannot, therefore be used as a namespace:

puts M::bar # => undefined method `bar' for M:Module
puts C.bar  # => this is bar

But, a module is an just an object of class Module, as we can demonstrate

puts M.class   # => Module

This means that we can do something crazy. We can mix a module into itself so that its methods become both instance and module methods.

module M
  extend self
  def bar
    puts "bar"
  end
end
puts M::bar # => this is bar
puts C.bar  # => this is bar
starfry
  • 9,273
  • 7
  • 66
  • 96