"Robert Klemme" <bob.news / gmx.net> schrieb im Newsbeitrag
news:2o6nn5F7gml3U1 / uni-berlin.de...
>
> "T. Onoma" <transami / runbox.com> schrieb im Newsbeitrag
> news:200408141028.42017.transami / runbox.com...
> > On Saturday 14 August 2004 10:06 am, Robert Klemme wrote:
> > > You didn't say so in your original post.  And as far as I can see you
> have
> > > two modules in your example, too.  As you obviously noticed, you need
to
> > > identify those parts that should go into instances and those for the
> class
> > > *somehow*.  So having two separate modules is really the simplest way.
> >
> > Okay, more detail then.
> >
> > Currently I have a class that can be subclassed to inherit behavior, but
I
> > want to turn that into a mixin module instead. Problem is that the class
> has
> > class methods that need to be inherited too. Can't do that with a
module,
> so
> > I had to figure out a way. Of course I could use two *seperate* modules,
> as
> > you say, but then the lib user would have to add two lines of code (an
> > include and an extend) to get functionality that really belongs
together.
> >
> > So let me ask it this way: I have class behavior and instance behavior
> that
> > needs to encapsulated into a single mixin unit. How to do it?
>
> You probably want this which works with a single (!) module.  Ha!
>

This is a bit nicer:

module Foo
  # class code
  class <<self
    attr_accessor :foo

    def append_features(cl)
      # need a copy of me to avoid state interference
      copy = dup
      cls = class<<cl;self;end

      copy.singleton_methods.each do |m|
        cls.send(:define_method, m, copy.method(m).to_proc)
      end

      super
    end
  end

  # instance code
  attr_accessor :bar
end

> Foo.foo = "Foo.foo"
> p Foo.foo
>
> class Bar
>   include Foo
> end
>
> bar = Bar.new
> bar.bar = "bar.bar"
> p bar.bar
>
> Bar.foo = "Bar.foo"
> p Bar.foo
> # ensure Foo.foo is unchanged
> p Foo.foo
>
>
> Regards
>
>     robert
>