From: Robert Dober Date: 2007-07-24T17:38:13+09:00 Subject: Re: Inherited & load On 7/24/07, Todd Benson wrote: > On 7/23/07, F. Senault wrote: > > Hello. > > > > I've written a mechanism to dynamically load plugins inheriting from a > > base class, using the self.inherited method. > > > > Now, in an irb session, I noticed that, even if I (re)load the classes, > > the self.inherited is only triggered once. Short example : > > > > > ruby -v > > ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-freebsd6] > > > > > cat first.rb > > #! /usr/local/bin/ruby > > load "test.rb" > > load "test.rb" > > > > > cat test.rb > > #! /usr/local/bin/ruby > > class Test > > def self.inherited(c) > > puts "#{c} inherited Test !" > > end > > end > > load "test2.rb" > > > > > cat test2.rb > > #! /usr/local/bin/ruby > > puts "In #{__FILE__}." > > class Test2 < Test ; end > > > > > ruby first.rb > > In ./test2.rb. > > Test2 inherited Test ! > > In ./test2.rb. > > > > Is there a trick somewhere that would allow me to trigger the inherited > > method at each time the file containing the "sub-class" (e.g. Test2) is > > loaded ? > > > > (The real plugin class, if there is a need, is here : > > http://www.lacave.net/~fred/projets/plugin.rb ) > > > > Fred > > This is probably not much help, but you got me to learn a couple of > things while playing around. > > First of all, I don't think you can inherit more than once without > removing the constant. Once you've declared class B < A then that's > it until removed. For example, > > irb> class A; def self.inherited(s); puts "#{s}!"; end; end > => nil > irb> class B < A; end > B! > => nil > irb> class B < A; end > => nil > irb> class C;end > => nil > irb> class B < C; end > =>TypeError: superclass mismatch for class B > ....blah blah > > But, if you use a module, > > $ cat m.rb > module M > class A > def self.inherited o > puts "A inherited by #{o}!" > end > end > def self.delete const > remove_const const.intern > end > end > > $ cat test.rb > require "m" > > puts "\nConstants: #{M.constants.inspect}" > print "First inherit: " > class M::B < M::A; end > > puts "\nConstants: #{M.constants.inspect}" > print "Second try at inherit: " > class M::B < M::A; end > > print "\n\nDelete B" > M::delete "B" > puts "\nConstants: #{M.constants.inspect}" > print "Try inherit now:" > class M::B < M::A; end > puts > $ > > Todd > > Hmm not sure how this fits in but what about include instead of inherit, does this not what you want to achieve? The more I am thinking about it I feel that this might indeed be what is needed as Module#included is executed all the time the include statement is called, hopefully Fred can use inclusion instead of inheritance. Cheers Robert -- I always knew that one day Smalltalk would replace Java. I just didn't know it would be called Ruby -- Kent Beck