From: Rick DeNatale Date: 2007-04-03T10:03:50+09:00 Subject: Re: Find the fully qualified name of a class from a string On 3/31/07, Nasir Khan wrote: > Here is an abridged (out of context) version of my original solution. (which > I am using now) > ----- > nasir@sparkle:misc>cat find_class_name.rb > > module EmptyModule > def EmptyModule.clear_all > constants.each {|x| remove_const(x.to_sym)} > end > end > > @my_classes = [] > > def class_from_string(str) > EmptyModule.clear_all # clean the slate > EmptyModule.module_eval(str) > end > > cstr = < module B > class A > def a > puts "hello" > end > end > end > module B > class C > end > class D > end > end > EOF > > # This string will usually come from some external invocation of this > function > > class_from_string(cstr) > > > def find_class mod > mod.constants.each do |str| > m = mod.const_get(str) > if m.class == Module > find_class(m) > else > cname = m.to_s > cname = cname.match(/EmptyModule::/).post_match > @my_classes << cname > end > end > end > > > find_class( EmptyModule ) > puts @my_classes.uniq > > --------------- > > And the result - > > nasir@sparkle:misc>ruby find_class_name.rb > B::D > B::C > B::A > > ---------------- > > I guess I will stick with this solution. set_trace_func usage is very > interesting but as I could have potentially several such evaluations going > on in parallel, I would go with the solution above. > > Comments criticisms welcome. This is still not thread safe since if you are doing this on two different threads they are sharing the EmptyModule. Here's my variation using your approach but with an anonymous module to do the module_eval: rick@frodo:/public/rubyscripts$ cat find_classes2.rb class String def all_class_names mod = Module.new mod.module_eval(self) mod.all_class_names end end class Module def all_class_names class_names = [] constants.each do |const_name| const = const_get(const_name) case const when Class class_names << const.to_s.split(/::/,2)[1] when Module class_names += const.all_class_names end end class_names.uniq end end cstr = <