extend keyword in class definition

R

ruud grosmann

Hi list,

I am reading the book 'design patterns in ruby'. On page 201 I find
this code example:

require 'forwardable'

class WriterDecorator
extend Forwardable

def_delegators :mad:real_writer, :write_line, :rewind, :pos, :close

def initialize (real_writer)
@real_writer = real_writer
end
end


I am a bit surprised by the 'extend Forwardable' line. Can anybody
explain me what this is? Is it the same as 'include Forwardable' or is
it the same as 'class WriterDecorator < Forwardable'?

thanks in advance, Ruud
 
J

James Coglan

[Note: parts of this message were removed to make it a legal post.]
I am a bit surprised by the 'extend Forwardable' line. Can anybody
explain me what this is? Is it the same as 'include Forwardable' or is
it the same as 'class WriterDecorator < Forwardable'?


It's neither. extend() is method that all objects have (classes are objects
too). It takes the methods from a module (in this case Forwardable) and adds
them as singleton methods to the object. Forwardable contains the method
'def_delegators', which we see here has been added as a singleton method to
WriterDecorator.
 
S

Sebastian Hungerecker

ruud said:
I am a bit surprised by the 'extend Forwardable' line. Can anybody
explain me what this is? Is it the same as 'include Forwardable' or is
it the same as 'class WriterDecorator < Forwardable'?

No, it's the same as WriterDecorator.extend Forwardable or
class <<WriterDecorator
include Forwardable
end
I.e. the module gets included in the singelton class of WriterDecorator, not
in WriterDecorator itself (or in other words: the module's methods get added
as singleton methods of the class instead of as instance methods)
 
D

David A. Black

Hi --

Hi list,

I am reading the book 'design patterns in ruby'. On page 201 I find
this code example:

require 'forwardable'

class WriterDecorator
extend Forwardable

def_delegators :mad:real_writer, :write_line, :rewind, :pos, :close

def initialize (real_writer)
@real_writer = real_writer
end
end


I am a bit surprised by the 'extend Forwardable' line. Can anybody
explain me what this is? Is it the same as 'include Forwardable' or is
it the same as 'class WriterDecorator < Forwardable'?

It's like a per-object include operation.

module M
def speak
puts "Hi!"
end
end

obj = Object.new
obj.extend(M)
obj.speak # "Hi!"

The example you've got extends the class object WriterDecorator. It's
like this:

class C
extend M
end

C.speak # "Hi!"


David

--
Rails training from David A. Black and Ruby Power and Light:
Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
Advancing with Rails January 19-22 Fort Lauderdale, FL *
* Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!
 
R

ruud grosmann

It's neither. extend() is method that all objects have (classes are objects
too). It takes the methods from a module (in this case Forwardable) and adds
them as singleton methods to the object. Forwardable contains the method
'def_delegators', which we see here has been added as a singleton method to
WriterDecorator.

thank you for your replies. But I'm afraid that I need some more
explanation. Isn't a singleton method a method that applies to the
singleton class of one object? And in this case we're talking about a
class, not an object?

As such, Forwardable is mixed in, is my first thought. What have I
understood wrongly?

regards, RUud
 
D

David A. Black

Hi --

thank you for your replies. But I'm afraid that I need some more
explanation. Isn't a singleton method a method that applies to the
singleton class of one object? And in this case we're talking about a
class, not an object?

As such, Forwardable is mixed in, is my first thought. What have I
understood wrongly?

Classes *are* objects.

c = Class.new # c is an object whose class is Class
c.extend(SomeModule)

Every class is an instance of the class Class, so you can extend
classes just like other objects.

I've always said that the answer to 75% of all questions about Ruby
is: Classes are objects :) It's definitely a very key thing.


David

--
Rails training from David A. Black and Ruby Power and Light:
Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
Advancing with Rails January 19-22 Fort Lauderdale, FL *
* Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!
 
S

Sebastian Hungerecker

ruud said:
Isn't a singleton method a method that applies to the
singleton class of one object?

It is a method that is defined on the singleton class of an object, yes.
As a singleton class by definition only has one instance that means that a
singleton method is a method that can be called on a single object and that
object only.
And in this case we're talking about a
class, not an object?

A class is an object:=> -605959678
As such, Forwardable is mixed in, is my first thought.

It is mixed in. It's mixed into WriterDecorator's singleton class.
What have I understood wrongly?

I'm not sure. Maybe you mistakenly assumed that a class is its own singleton
class?

HTH,
Sebastian
 
D

David A. Black

Hi --

It is a method that is defined on the singleton class of an object, yes.
As a singleton class by definition only has one instance that means that a
singleton method is a method that can be called on a single object and that
object only.

Although:

class C
end
class D < C
end

def C.x
end

D.x # subclass can call superclass's singleton methods

Technically, it's also true that if you extend an object with a
module, you're not really writing singleton methods, since the methods
in the module are available to other objects that use the module. The
singleton_method_added callback won't get called, for example.


David

--
Rails training from David A. Black and Ruby Power and Light:
Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
Advancing with Rails January 19-22 Fort Lauderdale, FL *
* Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!
 
J

janus

David

Am a little confused by your codes, from all I understood in these
threads.
module M
def speak
puts "Hi!"
end
end

obj = Object.new
obj.extend(M)
obj.speak

obj.speak should be Object.speak. Why is yours different? And your
second code agreed with singleton idiom.

Janus
 
D

David A. Black

Hi --

David

Am a little confused by your codes, from all I understood in these
threads.
module M
def speak
puts "Hi!"
end
end

obj = Object.new
obj.extend(M)
obj.speak

obj.speak should be Object.speak. Why is yours different? And your
second code agreed with singleton idiom.

I'm not sure what you mean by "should be". The way it's written,
Object does not have a "speak" method, but obj does. That's the effect
of extend: it adds module-based functionality to a single object.


David

--
Rails training from David A. Black and Ruby Power and Light:
Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
Advancing with Rails January 19-22 Fort Lauderdale, FL *
* Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!
 
R

ruud grosmann

OK. I think now I get what you mean.

To make sure I understood it right:
my mistake was that there are both singleton methods on classes and
singleton methods on instances of a class. Essentially the same,
because classes are objects too. In this case, we're talking about
singleton methods on the class WriterDecorator. This is done because
the Forwardable method 'def_delegators' is used by the class object
only, not by it's instances. Which would have been the case if
Forwardable was mixed in.
Please correct me if I'm wrong.

Thanks anyway for the time spent on helping me on this!

regards, Ruud
 
D

David A. Black

Hi --

OK. I think now I get what you mean.

To make sure I understood it right:
my mistake was that there are both singleton methods on classes and
singleton methods on instances of a class. Essentially the same,
because classes are objects too. In this case, we're talking about
singleton methods on the class WriterDecorator. This is done because
the Forwardable method 'def_delegators' is used by the class object
only, not by it's instances. Which would have been the case if
Forwardable was mixed in.
Please correct me if I'm wrong.

The only thing I'd add is that it's not really accurate to describe
methods defined in a module as "singleton methods" of an object that
extends itself with the module. A singleton method is really a method
defined in the object's singleton class itself.


David

--
Rails training from David A. Black and Ruby Power and Light:
Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
Advancing with Rails January 19-22 Fort Lauderdale, FL *
* Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!
 

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,774
Messages
2,569,598
Members
45,158
Latest member
Vinay_Kumar Nevatia
Top