Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby modules and extend self

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!

like image 621
joeellis Avatar asked Jul 28 '10 22:07

joeellis


People also ask

What is Module_function in Ruby?

module_function(*args) private. Creates module functions for the named methods. These functions may be called with the module as a receiver, and also become available as instance methods to classes that mix in the module. Module functions are copies of the original, and so may be changed independently.

What is self method in Ruby?

self is a special variable that points to the object that "owns" the currently executing code. Ruby uses self everwhere: For instance variables: @myvar. For method and constant lookup. When defining methods, classes and modules.

What is the difference between extend and include in Ruby?

In simple words, the difference between include and extend is that 'include' is for adding methods only to an instance of a class and 'extend' is for adding methods to the class but not to its instance.

What is class << self Ruby?

class << self definition is used often within a class, that new Ruby developers might think that it's some kind syntactic sugar available only for classes which allows to add class methods.


3 Answers

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.

like image 142
horseyguy Avatar answered Oct 06 '22 07:10

horseyguy


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

include M
greet
like image 31
Adrian Avatar answered Oct 06 '22 07:10

Adrian


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
like image 38
starfry Avatar answered Oct 06 '22 05:10

starfry