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.