Ruby for Rails p.462-464 - why include vs. extend?

Discussion in 'Ruby' started by Jeff Cohen, Oct 16, 2006.

  1. Jeff Cohen

    Jeff Cohen Guest

    Making my way through Ruby for Rails (excellent book, David), but am
    puzzled by the explanation of why Rails jumps through hoops to turn
    Module instance methods into class methods.

    On p. 463, David represents the situation sans Rails:

    module A
    module M
    module ClassMethods
    def some_method
    #...
    end

    def included(c)
    c.extend(ClassMethods)
    end
    end
    end

    and then a class later that does this:

    class B
    include A::M
    end

    The goal as for M::ClassMethods to become class methods of B. Whew.

    Here are my questions:

    1. Why can't class B just extend A::M::ClassMethods? Why use include
    and therefore necessitate this whole indirect approach? Must be some
    advantage that I'm not seeing?

    In other words, why couldn't this have worked?

    class B
    extend A::M::ClassMethods
    end

    and then there's no need M::included() needed at all?

    2. I guess because M::included() was overridden, class B did not get any
    instance methods - which I think would have normally been the case with
    an include statement. SO what if you wanted the "normal" inclusion
    behavior, but also wanted to do something "extra" when your module is
    included?

    Thanks!
    Jeff

    --
    Posted via http://www.ruby-forum.com/.
     
    Jeff Cohen, Oct 16, 2006
    #1
    1. Advertising

  2. Jeff Cohen

    Jan Svitok Guest

    On 10/16/06, Jeff Cohen <> wrote:
    > Making my way through Ruby for Rails (excellent book, David), but am
    > puzzled by the explanation of why Rails jumps through hoops to turn
    > Module instance methods into class methods.
    >
    > On p. 463, David represents the situation sans Rails:
    >
    > module A
    > module M
    > module ClassMethods
    > def some_method
    > #...
    > end
    >
    > def included(c)
    > c.extend(ClassMethods)
    > end
    > end
    > end
    >
    > and then a class later that does this:
    >
    > class B
    > include A::M
    > end
    >
    > The goal as for M::ClassMethods to become class methods of B. Whew.
    >
    > Here are my questions:
    >
    > 1. Why can't class B just extend A::M::ClassMethods? Why use include
    > and therefore necessitate this whole indirect approach? Must be some
    > advantage that I'm not seeing?
    >
    > In other words, why couldn't this have worked?
    >
    > class B
    > extend A::M::ClassMethods
    > end
    >
    > and then there's no need M::included() needed at all?
    >
    > 2. I guess because M::included() was overridden, class B did not get any
    > instance methods - which I think would have normally been the case with
    > an include statement. SO what if you wanted the "normal" inclusion
    > behavior, but also wanted to do something "extra" when your module is
    > included?
    >
    > Thanks!
    > Jeff


    1. The reason in unification - you don't need to remember where to use
    include and where extend, and this way you get both instance and class
    methods.

    2. overriding include should have no impact on actual method
    including. It's just a callback. All the stuff is being done in
    append_features. (At least that's what documentation says.)
    So either the docs are wrong, or your problem is somewhere else.
     
    Jan Svitok, Oct 16, 2006
    #2
    1. Advertising

  3. Jeff Cohen

    Guest

    Hi --

    On Mon, 16 Oct 2006, Jeff Cohen wrote:

    > Making my way through Ruby for Rails (excellent book, David), but am
    > puzzled by the explanation of why Rails jumps through hoops to turn
    > Module instance methods into class methods.
    >
    > On p. 463, David represents the situation sans Rails:
    >
    > module A
    > module M
    > module ClassMethods
    > def some_method
    > #...
    > end
    >
    > def included(c)
    > c.extend(ClassMethods)
    > end
    > end
    > end
    >
    > and then a class later that does this:
    >
    > class B
    > include A::M
    > end
    >
    > The goal as for M::ClassMethods to become class methods of B. Whew.
    >
    > Here are my questions:
    >
    > 1. Why can't class B just extend A::M::ClassMethods? Why use include
    > and therefore necessitate this whole indirect approach? Must be some
    > advantage that I'm not seeing?


    The goal is to be able to do one "include" and have both instance
    methods and class methods added to the class that's doing the
    including.

    > In other words, why couldn't this have worked?
    >
    > class B
    > extend A::M::ClassMethods
    > end
    >
    > and then there's no need M::included() needed at all?


    You'd have to do:

    class B
    include A::M
    extend A::M::ClassMethods
    end

    to get the same effect.

    > 2. I guess because M::included() was overridden, class B did not get any
    > instance methods - which I think would have normally been the case with
    > an include statement. SO what if you wanted the "normal" inclusion
    > behavior, but also wanted to do something "extra" when your module is
    > included?


    You still get the normal behavior -- that is, class B will still mix
    in any instance methods defined in A::M.


    David

    --
    David A. Black |
    Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
    DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
    [1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
    [2] http://dablog.rubypal.com | [4] http://www.rubycentral.org
     
    , Oct 16, 2006
    #3
  4. Jeff Cohen

    Jeff Cohen Guest

    unknown wrote:
    > You still get the normal behavior -- that is, class B will still mix
    > in any instance methods defined in A::M.
    >


    Got it! Sorry for my oversight.

    Thanks,
    Jeff

    --
    Posted via http://www.ruby-forum.com/.
     
    Jeff Cohen, Oct 16, 2006
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,984
    Smokey Grindel
    Dec 2, 2006
  2. Andreas Bogenberger
    Replies:
    3
    Views:
    930
    Andreas Bogenberger
    Feb 22, 2008
  3. David Morgan
    Replies:
    2
    Views:
    278
    Anthony Jones
    Jun 9, 2006
  4. Daniel Berger
    Replies:
    3
    Views:
    113
    Daniel Berger
    Oct 30, 2004
  5. Alexandru Popescu

    include and extend Module - Ruby Way

    Alexandru Popescu, Aug 21, 2005, in forum: Ruby
    Replies:
    9
    Views:
    132
    Devin Mullins
    Aug 22, 2005
Loading...

Share This Page