From: Robert Klemme Date: 2004-12-09T21:27:28+09:00 Subject: Re: Inheritance, mixins and initializers "Johan Nilsson" schrieb im Newsbeitrag news:1102594375.344eddcc1c357ac539046c764cd8c6b8@teranews... > Hi, > > I've got a question regarding inheritance, mixins, order of initialization > and calling module/super class "initializers". I'd like to do something > along the lines of (pseudo-ruby code): > > --- > class Base > def initialize(field_count) > @fields = Array.new(field_count) > end > end > > module FooMixin > def initialize(foo_field) > @foo_field = foo_field > self.fields[@foo_field] = Foo.new > end > > def foo > self.fields[@foo_field] > end > end > > module BarMixin > def initialize(bar_field) > @bar_field = bar_field > self.fields[@bar_field] = Bar.new > end > > def bar > self.fields[@bar_field] > end > end > > class Derived < Base > include FooMixin > include BarMixin > def initialize > super(2) > FooMixin(0) > BarMixin(1) > end > end > > --- > > Obviously this doesn't work - is there any way of achieving something > similar? The Foo/Bar mixins depend on Base being initialized before them > (ok, maybe not in this particular example). I don't know which real problem you are trying to solve. I can think of several other approaches. You might want to store your mixin created instances directly in instance variables and record only the names of these. class Foo;end class Bar;end class Base attr_reader :fields def initialize() @fields = [] end def add_field(name) @fields << name end def all_fields() @fields.map {|f| instance_variable_get f} end end module FooMixin attr_reader :foo def initialize(*a,&b) super @foo = Foo.new add_field "@foo" end end module BarMixin attr_reader :bar def initialize(*a,&b) super @bar = Bar.new add_field "@bar" end end class Derived < Base include FooMixin include BarMixin def initialize super end end Or you can determine the position automatically. class Foo;end class Bar;end class Base attr_reader :fields def initialize() @fields = [] end end module FooMixin def initialize(*a,&b) super @foo_field = self.fields.size self.fields << Foo.new end def foo self.fields[@foo_field] end end module BarMixin def initialize(*a,&b) super @bar_field = self.fields.size self.fields << Bar.new end def bar self.fields[@bar_field] end end class Derived < Base include FooMixin include BarMixin def initialize super end end Kind regards robert