On Fri, 7 Oct 2005, ES wrote:

> Robert Klemme wrote:
>> itsme213 wrote:
>> 
>>> What are good design techniques for this e.g. if the module adds some
>>> instance variables to its included class?
>>> 
>>> module M
>>>  def f
>>>    @f
>>>  end
>>>  # how to initialize @f ?
>>> end
>>> 
>>> class A
>>>  include M
>>> end
>>> Thanks.
>> 
>> 
>> Do it like this and the module initialite will seamlessly integrate into
>> the class inheritance chain:
>> 
>> module M
>>   def initialize(*a,&b)
>>     super
>>     @f = 10
>>   end
>> end
>
> This does not work directly if the class itself defines an #initialize
> as it will take precedence over the module version.

easy:

   harp:~ > cat a.rb
   require 'traits'

   module M
     trait 'f' => 42
   end

   class C
     include M
   end

   c = C::new

   p c.f


   harp:~ > ruby a.rb
   42

hard:

   harp:~ > cat a.rb
   module M
     ATTRIBUTES = {
       'f' => 42
     }

     def self::inited_attr a
       module_eval <<-code
         def #{ a }
           __m_init
           @#{ a }
         end
       code
     end

     ATTRIBUTES.keys.each{ |a| inited_attr a }

     def __m_init
       return if @__m_init
       ATTRIBUTES.each{ |a,v| instance_variable_set "@#{ a }", v }
       @__m_init = true
     end
   end

   class C
     include M
   end

   c = C::new

   p c.f


   harp:~ > ruby a.rb
   42


hth.

btw. i just broke the traits installer so download v 0.6.0 (not 0.7.0) if you
get it - i'm working on a fix now...

-a
-- 
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| Your life dwells amoung the causes of death
| Like a lamp standing in a strong breeze.  --Nagarjuna
===============================================================================