25

Possible Duplicate:
What is the difference between include and extend in Ruby?

Given:

module my_module
  def foo
    ...
  end
end

Question 1

What is the difference between:

class A
  include my_module
end

and

class A
  extend my_module
end

Question 2

Will foo be considered an instance method or a class method ? In other words, is this equivalent to:

class A
  def foo
    ...
  end
end

or to:

class A
  def self.foo
    ...
  end
end

?

Community
  • 1
  • 1
Misha Moroshko
  • 166,356
  • 226
  • 505
  • 746

2 Answers2

29

I wrote a blog posting about this a long time ago here.

When you're "including" a module, the module is included as if the methods were defined at the class that's including them, you could say that it's copying the methods to the including class.

When you're "extending" a module, you're saying "add the methods of this module to this specific instance". When you're inside a class definition and say "extend" the "instance" is the class object itself, but you could also do something like this (as in my blog post above):

module MyModule
  def foo
    puts "foo called"
  end
end

class A
end

object = A.new
object.extend MyModule

object.foo #prints "foo called"    

So, it's not exactly a class method, but a method to the "instance" which you called "extend". As you're doing it inside a class definition and the instance in there is the class itself, it "looks like" a class method.

Maurício Linhares
  • 39,901
  • 14
  • 121
  • 158
  • 2
    It's actually the other way around... includes adds instance methods and extends adds class methods...why does this have 30 votes? – Jose Paez Dec 22 '21 at 04:59
  • 1
    The question isn't referring to extending on a specific instance which is what you're doing with `object.extend MyModule` it's referring to extending in the body of the class in which the receiver (`self`) is the class itself, hence it's adding class methods. – Premez Feb 28 '23 at 17:57
20

1) include adds methods, constants, and variables on instances of class A; extend adds those things to the instance of the Class instance A (effectively defining class methods).

include my_module will allow this: A.new.foo

extend my_module will allow this: A.foo

More generally, include only makes sense on a Class or Module, while extend can be used to add methods to any Object.

2) In effect: when using include, foo is an instance method of A ... when using extend, foo is a class method.

Andy Lindeman
  • 12,087
  • 4
  • 35
  • 36