From: "David A. Black" Date: 2005-07-21T01:46:16+09:00 Subject: Re: Variable class (newb question) Hi -- On Thu, 21 Jul 2005, Zach Dennis wrote: > The only thing I don't like about the above solution is potential insecurity > if someone passes in " ; B" , the would execute. This > could changed to be more secure if you were always using toplevel classes... > > > def get_class_for_string( class_name ) > eval("#{class_name}.new") if Object.constants.include?( class_name ) > end > > Which the above code makes sure that the passed in class_name has been > defined on the top-level Object otherwise it will return nil. This won't work > for things like "MyModule::B" or "MyClass::InnerClass:B", although you could > change it to work. And here is the modified version to make it work across > the board: > > def get_class_for_string( class_name ) > last_constant = Object > class_name.split( /::/ ).each do |cons_str| > if last_constant.constants.include?( cons_str ) > last_constant = eval( "last_constant::#{cons_str}" ) > else > return nil > end > end > eval("#{last_constant}.new") > end A more concise and eval-free way to do that is: class Module def deep_const_get(str) str.split("::").inject(Object) {|a,b| a.const_get(b) } end end "Traditional", as they say for folk songs :-) I've written it and others have too -- I don't know who first. Note that there's no need to test for failure; it will fail if any call to const_get fails. David -- David A. Black dblack@wobblini.net