mixins and extend (was: Attempted roadmap of future instance variables....)

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

  1. T. Onoma

    T. Onoma Guest

    Can anyone take a look at this and tell me what the hek is happening with
    extend? (as in Pickaxe Chapter 19)

    ruby-talk:87344

    I thought I finally understood, but now I'm just confused again.

    Thanks,
    T.


    Copy of 87344 follows:

    On Friday 05 December 2003 08:26 pm, T. Onoma wrote:
    > On Friday 05 December 2003 07:02 pm, Austin Ziegler wrote:
    > > It is a mix-in.
    > >
    > > class A; end
    > > class B; include Transaction::Simple; end
    > > x = A.new
    > > y = B.new
    > > x.extend(Transaction::Simple)
    > > class << x; self; end.ancestors
    > > => [Transaction::Simple, A, Object, Kernel]
    > > class << y; self; end.ancestors
    > > => [B, Transaction::Simple, Object, Kernel]
    > >
    > > It's just that #extend mixes into the object's singleton class.

    >
    > Hmm... Well, you actually prove my point. Transaction::Simple is coming
    > before A in the first case, and after B in the second. Quite different form
    > the ordinary mixin-in. Yet you'll have to excuse my while I scream
    > "Arrrrgggghhh!!!" b/c it is even more complex than I realized. So, yes, it
    > is techinaclly a mix-in per se, but since it is a mix-in on the sinlgeton
    > and not the class itself, it is more akin to a singleton. Or at least one
    > would think! But it seems it is actually more akin to just
    > redefining/restating the class:
    >
    > module M
    > def happy; print "M"; super if defined?(super); end
    > end
    >
    > class MC
    > def happy; print "M"; super if defined?(super); end
    > end
    >
    > class S < MC
    > def happy; print "x"; super if defined?(super); end
    > end
    >
    > class I
    > include M
    > def happy; print "x"; super if defined?(super); end
    > end
    >
    > class E
    > def happy; print "x"; super if defined?(super); end
    > end
    >
    > class C
    > def happy; print "x"; super if defined?(super); end
    > end
    >
    > s = S.new
    >
    > a = I.new
    >
    > b = E.new
    > b.extend(M)
    >
    > c = C.new
    > def c.happy; print "M"; super if defined?(super); end
    >
    > print "superclass: "; s.happy
    > print "\t", class << s; self; end.ancestors.inspect; puts
    >
    > print " include: "; a.happy
    > print "\t", class << a; self; end.ancestors.inspect; puts
    >
    > print " extend: "; b.happy
    > print "\t", class << b; self; end.ancestors.inspect; puts
    >
    > print " singleton: "; c.happy
    > print "\t", class << c; self; end.ancestors.inspect; puts
    >
    > This produces:
    >
    > superclass: xM [S, MC, Object, Kernel]
    > include: xM [I, M, Object, Kernel]
    > extend: M [M, E, Object, Kernel]
    > singleton: Mx [C, Object, Kernel]
    >
    > Notice in the singleton that "M" is invisible, but it does in fact exist
    > anonymously before C.
    >
    > I have to say, I'm actually very disturbed to see the x missing in the
    > extend. Where the heck did it go? Extending just redefined the happy method
    > altogether! That's not something I would call "extend".
    >
    > T.
     
    T. Onoma, Dec 6, 2003
    #1
    1. Advertising

  2. T. Onoma

    ts Guest

    >>>>> "T" == T Onoma <> writes:

    T> Can anyone take a look at this and tell me what the hek is happening with
    T> extend? (as in Pickaxe Chapter 19)

    Well, I've not understood your problem.

    To simplify : by default (because it's possible to redefine what do ruby)
    an extend can be seen as an include in the singleton class.

    For your example

    >> c = C.new
    >> def c.happy; print "M"; super if defined?(super); end


    [...]

    >> singleton: Mx [C, Object, Kernel]
    >>
    >> Notice in the singleton that "M" is invisible, but it does in fact exist
    >> anonymously before C.


    M is not invisible : it just don't exist. You have just defined a method
    #happy for `c', like the module M define a method #happy


    Guy Decoux
     
    ts, Dec 6, 2003
    #2
    1. Advertising

  3. T. Onoma

    T. Onoma Guest

    On Saturday 06 December 2003 04:31 pm, ts wrote:
    > >>>>> "T" == T Onoma <> writes:

    >
    > T> Can anyone take a look at this and tell me what the hek is happening
    > with T> extend? (as in Pickaxe Chapter 19)
    >
    > Well, I've not understood your problem.


    Thanks for responding, Guy. I'll explain better.

    > To simplify : by default (because it's possible to redefine what do ruby)
    > an extend can be seen as an include in the singleton class.


    "seen as an include in the singleton class": That's what confuses me. I can
    "see" this by combing the diagrams on Pickaxe pg. 246 and 247, no problem.
    But it dosen't explain to me why x isn't printed in my extend example.

    (I wish there way a way I could draw a picture of it here)

    > >> singleton: Mx [C, Object, Kernel]
    > >>
    > >> Notice in the singleton that "M" is invisible, but it does in fact exist
    > >> anonymously before C.

    >
    > M is not invisible : it just don't exist. You have just defined a method
    > #happy for `c', like the module M define a method #happy


    Indeed I have defined that method, but it is put in a an unnamed class, i.e.
    the singleton class. (Pickaxe Figure 19.2 on page 246, has a diagram of it.)
    I'm simply refering to it as M, analogous to the rest of the examples. This
    is why M is printed before x and dosen't simply replace x.

    T.

    [NOTE: I figured it out and it may be a bug in Ruby. At the the very least it
    is a "bugaboo". I'll explain in next message -T.]
     
    T. Onoma, Dec 6, 2003
    #3
  4. T. Onoma

    T. Onoma Guest

    Take a look at this:

    class MC
    def happy; print "C"; super if defined?(super); end
    end

    module M
    def happy; print "M"; super if defined?(super); end
    end

    class S < MC
    include M
    def happy; print "x"; super if defined?(super); end
    end

    s = S.new

    print "superclass: "; s.happy
    print "\t", class << s; self; end.ancestors.inspect; puts

    Outputs:

    superclass: xM [S, M, MC, Object, Kernel]

    Now look at this:

    class MC
    def happy; print "C"; super if defined?(super); end
    end

    module M
    def happy; print "M"; super; end
    end

    class S < MC
    include M
    def happy; print "x"; super if defined?(super); end
    end

    s = S.new

    print "superclass: "; s.happy
    print "\t", class << s; self; end.ancestors.inspect; puts

    Outputs:

    superclass: xMC [S, M, MC, Object, Kernel]

    The last is what one would expect. Seems that defined?(super) dosen't work
    with mixins even though calling super does. What do you make of that? Bug?

    T.
     
    T. Onoma, Dec 6, 2003
    #4
  5. T. Onoma

    ts Guest

    >>>>> "T" == T Onoma <> writes:

    T> superclass: xM [S, M, MC, Object, Kernel]

    svg% cat b.rb
    #!./ruby -v
    class MC
    def happy; print "C"; super if defined?(super); end
    end

    module M
    def happy; print "M"; super if defined?(super); end
    end

    class S < MC
    include M
    def happy; print "x"; super if defined?(super); end
    end

    s = S.new

    print "superclass: "; s.happy
    print "\t", class << s; self; end.ancestors.inspect; puts
    svg%

    svg% b.rb
    ruby 1.8.1 (2003-11-30) [i686-linux]
    superclass: xMC [S, M, MC, Object, Kernel]
    svg%


    Guy Decoux
     
    ts, Dec 6, 2003
    #5
  6. T. Onoma

    T. Onoma Guest

    On Saturday 06 December 2003 05:16 pm, ts wrote:
    > svg% b.rb
    > ruby 1.8.1 (2003-11-30) [i686-linux]
    > superclass: xMC [S, M, MC, Object, Kernel]
    > svg%


    So what do you know:

    ruby 1.8.0 (2003-08-04) [i686-linux]
    superclass: xM [S, M, MC, Object, Kernel]

    Cool, so it's been fixed! And I do understand correctly, and I have all along.
    Guess it's time to upgrade.

    Whew! That really scared the hek out of me. My world started to come tumbling
    down. But super Guy was there to keep the sky from falling :)

    Thanks, Guy.
    T.
     
    T. Onoma, Dec 6, 2003
    #6
    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. Frank D. Greco
    Replies:
    0
    Views:
    348
    Frank D. Greco
    Mar 22, 2005
  2. David A. Black
    Replies:
    1
    Views:
    116
    Ben Giddings
    Dec 3, 2003
  3. Johannes Friestad

    Mixins and variables

    Johannes Friestad, Dec 7, 2005, in forum: Ruby
    Replies:
    1
    Views:
    97
    James Edward Gray II
    Dec 7, 2005
  4. Brubix

    Mixins and class variables

    Brubix, Dec 16, 2007, in forum: Ruby
    Replies:
    7
    Views:
    128
    Brubix
    Dec 17, 2007
  5. Dale Martenson

    Instance Variable in Mixins

    Dale Martenson, May 19, 2008, in forum: Ruby
    Replies:
    1
    Views:
    151
    Rick DeNatale
    May 20, 2008
Loading...

Share This Page