From: ara.t.howard@... Date: 2006-05-23T05:57:15+09:00 Subject: Re: initializing instance variables in a module On Tue, 23 May 2006, Jeff Rose wrote: > Well, it took a while but I found the answer. This is done in ActiveRecord > to wrap a possible setup method in the unit tests for auto-instrumentation of > fixtures. Once I knew what to look for, however, I found an old post by > Florian Gross that lays out the exact answer nicely: > > http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/129834 > > For educational purposes though, I'll explain a few things I found... > > 1) The append_features method is deprecated, and the included method is now > the preferred callback. This method is called when a module is included, and > it is passed the module that has done the including. > > 2) There is another callback, method_added, which is a meta-class method that > is called every time a new method is defined for its class, and the symbol > for the method name is passed. > > So, the trick is to add a custom method_added method to the meta-class of the > class that does the including by extending it in the included callback. The > custom method_added needs to redefine initialize after it is added so that it > does the custom setup, then calls the original. > > Phew... Too bad we can't just have another callback that lets us do this > easily. Maybe that feels too much like multiple inheritance or something? > > module Foo > def module_initialize > @myvar = Hash.new {|k,v| k[v] = []} > end > > def bar(key) > @mybar[key] > end > end > > Isn't this a common thing to want? and precisely one of the reasons i wrote traits - with traits you can simply ignore the issue altogether: harp:~ > gem install traits harp:~ > cat a.rb require 'rubygems' require 'traits' module Foo trait 'myvar' => Hash.new{|k,v| k[v] = []} def bar(key) myvar[key] end end class Bar include Foo end b = Bar.new p b.bar(:k) p b.myvar harp:~ > ruby a.rb [] {:k=>[]} ;-) -a -- be kind whenever possible... it is always possible. - h.h. the 14th dali lama