"Gavin Kistner" <gavin / refinery.com> schrieb im Newsbeitrag news:F761507A-0DD2-11D9-9F40-000A959CF5AC / refinery.com... > On Sep 23, 2004, at 9:29 AM, Robert Klemme wrote: >> You could store a set of method names in the base class and add a check >> method for sub classes. >> >> require 'set' >> >> class Base >> def self.inherited(cl) >> (@children ||= []) << cl >> def cl.inherited(cl2) superclass.inherited(cl2) end >> end > > Whoa. :-) <snip/> > c) While that second line is tricky, I actually prefer the hierarchical > storage which occurs without it, since it allows for creating a > hierarchical, visual representation of the class hierarchy. (Or is there a > much cleaner/more built-in way than the following?) > > class Foo > def self.inherited( k ) > (@subclasses ||= []) << k > #def k.inherited(k2) > superclass.inherited(k2) > end > end > > def self.show_subclasses( indent=0 ) > puts "\t"*indent + self.inspect > @ subclasses.each{ |k| > k.show_subclasses( indent+1 ) > } if @ subclasses.respond_to? :each > end You can do "if @subclasses" here because nil ~ false. > class Bar < self > class Jee < self; end > end > class Whee < self; end > end > class Foo2 < Foo; end > > Foo.show_subclasses( ) > #=> Foo > #=> Foo::Bar > #=> Foo::Bar::Jee > #=> Foo::Whee > #=> Foo2 > > >> diff = @mandatory - Set.new(cl.instance_methods) > > Ooh, nice, I was going to just yell on a first-not-found basis but the Set > is a very elegant way of doing it. > > > Thank you very much for your help, Robert. It's exactly what I needed! :) You're welcome! I'm glad I could help. robert