include vs. extend

D

Daniel DeLorme

I was under the impression that include and extend were basically module-level
and object-level versions of the same thing, that including a module at the
class level had the same effect as extending an object. But it seems there is a
big difference:

class Foo
include Enumerable
end
class Bar
def initialize
extend Enumerable
end
end
(class << Foo.new;self;end).ancestors #=> [Foo, Enumerable, Object, Kernel]
(class << Bar.new;self;end).ancestors #=> [Enumerable, Bar, Object, Kernel]

This makes a whole world of difference when you want to wrap certain methods
with additional functionality. In such cases you *have* to use extend (or ugly
techniques like aliasing the old method). Why the difference? In what cases
should I use include and what cases should I use extend?

Daniel
 
D

dblack

Hi --

I was under the impression that include and extend were basically
module-level and object-level versions of the same thing, that including a
module at the class level had the same effect as extending an object. But it
seems there is a big difference:

class Foo
include Enumerable
end
class Bar
def initialize
extend Enumerable
end
end
(class << Foo.new;self;end).ancestors #=> [Foo, Enumerable, Object, Kernel]
(class << Bar.new;self;end).ancestors #=> [Enumerable, Bar, Object, Kernel]

This makes a whole world of difference when you want to wrap certain methods
with additional functionality. In such cases you *have* to use extend (or
ugly techniques like aliasing the old method). Why the difference? In what
cases should I use include and what cases should I use extend?

It's understood that if you extend an object, it's because you *want*
to put the module ahead of the object's class in the method look-up
path. Otherwise, you'd put the functionality you want in the class
:) By the same token, it would be very unusual to put extend in
initialize.

Basically you use extend when you want to control behavior via modules
on a per-object basis. A common use is for classes:

module M
def meth
puts "Hi"
end
end

class C
extend M
end

C.meth # Hi

obj.extend(Mod) is equivalent to:

class << obj
include Mod
end

(or very nearly equivalent; there may be some arcane difference I'm
not remembering). So it's all really include operations -- but, when
done with extend, the class doing the including is a singleton class.


David

--
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
http://www.manning.com/black => RUBY FOR RAILS, the Ruby book for
Rails developers
http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log
(e-mail address removed) => me
 
K

Kent Sibilev

In the first case, the proxy that refers to the Enumerable module is
inserted between Foo class and Object class. In the second case, an
instance of a Bar class during initialization receives a new class
which is the same proxy object and this proxy's superclass is Bar
class. BTW, check out this book at http://rhg.rubyforge.org. It has a
very nice chapter about internal structure of Ruby object model.

Kent.

I was under the impression that include and extend were basically module-level
and object-level versions of the same thing, that including a module at the
class level had the same effect as extending an object. But it seems there is a
big difference:

class Foo
include Enumerable
end
class Bar
def initialize
extend Enumerable
end
end
(class << Foo.new;self;end).ancestors #=> [Foo, Enumerable, Object, Kernel]
(class << Bar.new;self;end).ancestors #=> [Enumerable, Bar, Object, Kernel]

This makes a whole world of difference when you want to wrap certain methods
with additional functionality. In such cases you *have* to use extend (or ugly
techniques like aliasing the old method). Why the difference? In what cases
should I use include and what cases should I use extend?

Daniel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top