append_features(mod) -- mod.kind_of? makes absolutely no sense

Discussion in 'Ruby' started by T. Onoma, Dec 14, 2003.

  1. T. Onoma

    T. Onoma Guest

    First of all, if class Class inherits class Module then why isn't
    append_features defined for Class?

    class Whatever
    append_features MyModule
    end
    # => undefined method `append_features' for Whatever:Class (NoMethodError)

    But even more nonsensical:

    class Module
    alias append_features_orig append_features
    def append_features(mod)
    p mod, mod.class
    append_features_orig(mod)
    end
    end
    module MyModule
    def wow
    puts "You have to be kidding!"
    end
    end
    class Test
    include MyModule
    end
    t = Test.new
    t.wow

    Produces:

    Test
    Class
    You have to be kidding!

    Its my understanding the include passes each Module to append_features, but
    that's not what append_features is saying. In fact, according to this
    append_features is appending Test to Test, even though it works fine. Please,
    tell me I'm over looking the obvious here.

    --
    T.
     
    T. Onoma, Dec 14, 2003
    #1
    1. Advertising

  2. T. Onoma

    Guest

    Hi,

    At Sun, 14 Dec 2003 16:45:41 +0900,
    T. Onoma wrote:
    > class Module
    > alias append_features_orig append_features
    > def append_features(mod)
    > p mod, mod.class

    p self # try this.
    > append_features_orig(mod)
    > end
    > end
    > module MyModule
    > def wow
    > puts "You have to be kidding!"
    > end
    > end
    > class Test
    > include MyModule
    > end
    > t = Test.new
    > t.wow


    --
    Nobu Nakada
     
    , Dec 14, 2003
    #2
    1. Advertising

  3. T. Onoma

    Christoph Guest

    "T. Onoma" <> wrote in message
    news:...
    > First of all, if class Class inherits class Module then why isn't
    > append_features defined for Class?
    >
    > class Whatever
    > append_features MyModule
    > end
    > # => undefined method `append_features' for Whatever:Class

    (NoMethodError)

    Isn't this the whole point of Module#undef (or undef_method)?

    class A
    def foo
    end
    end
    class B < A
    undef :foo
    end

    B.new.foo # undefined method `foo' ...

    ....

    > Its my understanding the include passes each Module to append_features,

    but
    > that's not what append_features is saying. In fact, according to this
    > append_features is appending Test to Test, even though it works fine.

    Please,
    > tell me I'm over looking the obvious here.


    Don't worry, you are overlooking the obvious:)

    class Module
    alias append_features_orig append_features
    def append_features(mod)
    # changed from p mod, mod.class
    p mod, self
    append_features_orig(mod)
    end
    end
    module MyModule
    def wow
    puts "You have to be kidding!"
    end
    end
    class Test
    include MyModule
    end
    t = Test.new
    t.wow

    /Christoph
     
    Christoph, Dec 14, 2003
    #3
  4. T. Onoma

    T. Onoma Guest

    On Sunday 14 December 2003 11:16 am, wrote:
    > Hi,
    >
    > At Sun, 14 Dec 2003 16:45:41 +0900,
    >
    > T. Onoma wrote:
    > > class Module
    > > alias append_features_orig append_features
    > > def append_features(mod)
    > > p mod, mod.class

    >
    > p self # try this.
    >
    > > append_features_orig(mod)
    > > end
    > > end
    > > module MyModule
    > > def wow
    > > puts "You have to be kidding!"
    > > end
    > > end
    > > class Test
    > > include MyModule
    > > end
    > > t = Test.new
    > > t.wow


    Okay, that at least clarifies where MyModule went. How did it become self? In
    #include it is the argument. Let me guess:

    def include(mod)
    mod.append_features(self)
    end

    By the way, PickAxe (my Bible) doesn't explain this correctly.

    --
    T.
     
    T. Onoma, Dec 14, 2003
    #4
  5. T. Onoma

    Guest

    Hi,

    At Mon, 15 Dec 2003 01:17:04 +0900,
    T. Onoma wrote:
    > Okay, that at least clarifies where MyModule went. How did it become self? In
    > #include it is the argument. Let me guess:
    >
    > def include(mod)
    > mod.append_features(self)
    > end


    More precisely,

    def include(*modules)
    modules.reverse_each do |mod|
    mod.append_features(self)
    mod.included(self)
    end
    end

    --
    Nobu Nakada
     
    , Dec 14, 2003
    #5
  6. T. Onoma

    Dave Thomas Guest


    > def include(mod)
    > mod.append_features(self)
    > end
    >
    > By the way, PickAxe (my Bible) doesn't explain this correctly.
    >


    Perhaps you might be more specific? I'm always interested in improving
    the text.


    Cheers

    Dave
     
    Dave Thomas, Dec 14, 2003
    #6
  7. T. Onoma

    Christoph Guest

    T. Onoma wrote:
    ....
    > def include(mod)
    > mod.append_features(self)
    > end
    >
    > By the way, PickAxe (my Bible) doesn't explain this correctly.


    Sure it does (unless you own a first edition)

    /Christoph
     
    Christoph, Dec 14, 2003
    #7
  8. T. Onoma

    T. Onoma Guest

    On Sunday 14 December 2003 06:02 pm, Dave Thomas wrote:
    > > def include(mod)
    > > mod.append_features(self)
    > > end
    > >
    > > By the way, PickAxe (my Bible) doesn't explain this correctly.

    >
    > Perhaps you might be more specific? I'm always interested in improving
    > the text.


    Hi Dave,

    According to Christoph I may just own a first addition. But just the same, my
    confusion came from pg. 350 in chp. 22 Built-in Classes, it says about
    Module.include(<aModule>+):

    Invokes Module.append_features on each parameter in turn.

    And under Module.append_features(aModule) is says:

    The contants and methods of aModule are added to the current module...

    This is ambigious b/c, before I knew, it read to me as if "Invokes
    Module.append_features on each parameter" meant append_features(aModule) not
    aModule.append_features(self). Which is exactly why I didn't understand why
    one couldn't use append_features like this:

    module AModule
    append_features(AnotherModule)
    end

    When what you really need to do is:

    module AModule
    AnotherModule.append_features(self)
    end

    Perhaps if you just added to Module.include, Nakada's "More precisely",

      def include(*modules)
        modules.reverse_each do |mod|
          mod.append_features(self)
          mod.included(self)
        end
      end

    That would make all the difference.

    Thanks for listening,
    T.
     
    T. Onoma, Dec 14, 2003
    #8
  9. T. Onoma

    Christoph Guest

    T. Onoma wrote:
    ....
    >
    > Invokes Module.append_features on each parameter in turn.
    >
    > And under Module.append_features(aModule) is says:
    >
    > The contants and methods of aModule are added to the current module...


    FYI - the online PickAxe version reads as:

    When this module is included in another, Ruby calls append_features in this
    module, passing it the receiving module in aModule. Ruby's default
    implementation is to add the constants, methods, and module variables of
    this module to aModule if this module has not already been added to aModule
    or one of its ancestors. See also Module#include on page 345.

    ....
    > Perhaps if you just added to Module.include, Nakada's "More precisely",
    >
    > def include(*modules)
    > modules.reverse_each do |mod|
    > mod.append_features(self)
    > mod.included(self)
    > end
    > end
    >
    > That would make all the difference.


    I agree adding this Module#include implementation might
    be helpful - perhaps even the "privacy-aware" version
    (note that the Module#included hook was (afaik) never added
    in the 1.6 series)

    class Module
    private
    def include(*modules)
    modules.reverse_each do |mod|
    mod.__send__:)append_features, self)
    mod.__send__:)included, self)
    end
    end
    end

    /Christoph
     
    Christoph, Dec 14, 2003
    #9
  10. T. Onoma

    Dave Thomas Guest

    On Dec 14, 2003, at 12:48, T. Onoma wrote:

    > This is ambigious b/c, before I knew, it read to me as if "Invokes
    > Module.append_features on each parameter" meant
    > append_features(aModule) not
    > aModule.append_features(self). Which is exactly why I didn't
    > understand why
    > one couldn't use append_features like this:
    >


    Yes - I see what you're saying: the text was too concise. In fact after
    seeing nobu's post I added his example to the text: look for it in an
    upcoming 'ri'.

    Cheers


    Dave

    Cheers

    Dave
     
    Dave Thomas, Dec 15, 2003
    #10
    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. Debashish Chakravarty

    when GOTO makes sense.

    Debashish Chakravarty, Nov 29, 2003, in forum: C Programming
    Replies:
    45
    Views:
    1,083
    Dan Pop
    Dec 9, 2003
  2. Replies:
    1
    Views:
    367
    Peter Otten
    Aug 30, 2006
  3. Replies:
    11
    Views:
    646
    Crouchinho
    Sep 26, 2006
  4. Replies:
    3
    Views:
    367
  5. Neroku
    Replies:
    6
    Views:
    10,223
    Chris Uppal
    Feb 8, 2007
Loading...

Share This Page