[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: self.included question

Xavier Noria

5/16/2007 8:23:00 PM

On May 16, 2007, at 10:02 PM, Dave Hoefler wrote:

> Hi there,
>
> I see the following code chunk in a lot of Rails plugins:
>
> def self.included(base)
> base.extend(ClassMethods)
> end
>
> module ClassMethods
> def method_one
> end
>
> def method_two
> end
> end
>
>
> I'm most curious about "self.included". I checked out the docs on
> 'included'
> (http://www.ruby-doc.org/core/classes/Module.ht...). They
> pointed to
> 'Module.append_features' (
> http://www.ruby-doc.org/core/classes/Module.ht...). Even after
> reading the docs, I'm still a little lost. Could someone break it
> down a
> little more than the docs? ...or point me at some other resource.
> I'd like
> to know "why" this is done.

If a module implements self.included the interpreter calls that
method whenever the module is included in another module or class,
which is passed as its single argument.

Object#extend on the other hand adds the instance methods of the
module or modules passed as arguments to the target object (as
singleton methods). If the object is a class, that means you are
making module instance methods available as class methods in that
class, and that's what base is when a module is being included in a
class.

In short, plugins put methods that will end up being class methods
(acts_as_something, say) in their own nested module, conventionally
called ClassMethods, and then include them in init.rb. For instance

ActiveRecord::Base.send(:include, MyModule)

That triggers inclusion when Rails boots, so your code is able to
call those class methods as if they belonged to the original API of
ActiveRecord::Base (in the example).

-- fxn



2 Answers

Robert Dober

5/16/2007 8:46:00 PM

0

On 5/16/07, Dave Hoefler <dhoefler@gmail.com> wrote:
<snip>
> module Office
> def self.included(base)
> base.extend(ClassMethods)
> end
>
> module ClassMethods
> def working(options={})
> # do something based off the options
> end
> end
>
> end
>
> In one of my models I can then access the method 'working' by:
>
> class ModelName < ActiveRecord::Base

#given that you include Office before
include Office
> working :task => "Take a break!"
> end
>
>
> Thanks again
>
> -Dave
Cheers
Robert

--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

Xavier Noria

5/16/2007 9:05:00 PM

0

On May 16, 2007, at 10:39 PM, Dave Hoefler wrote:

> Robert and Xavier (fxn) -
>
> Thank you for the explanations! That just cleared things up
> tremendously.
>
> So say I have this module (rails plugin):
>
> module Office
> def self.included(base)
> base.extend(ClassMethods)
> end
>
> module ClassMethods
> def working(options={})
> # do something based off the options
> end
> end
>
> end
>
> In one of my models I can then access the method 'working' by:
>
> class ModelName < ActiveRecord::Base
> working :task => "Take a break!"
> end

Exactly.

In regular Ruby you'd need to include Office by hand in the model
class, but in Rails it is normal (I'd say even expected) that the
plugin does the include in AR::Base for you in init.rb using the
idiom mentioned in the previous post.

-- fxn