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.