From: Troy Denkinger Date: 2006-03-04T03:15:59+09:00 Subject: Re: Dynamic Object Instantiation ------=_Part_9484_13175311.1141409740618 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Thanks for the followup. I also figured out how to search and found this: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/13414?help-en Which also helps. Thanks. On 3/1/06, Joel VanderWerf wrote: > > Troy Denkinger wrote: > > I'm sure this question has been asked and answered in the past, but > googling > > and searching the list archives isn't getting me much. It's probably a > case > > of me not searching correctly. So, if someone has a pointer on that > front, > > let me know. > > > > Basically, I want a class to dynamically load and instantiate objects. > > Here's the code that is supposed to do that: > > > > ComponentGatherer.rb > > --------------------------------- > > > > class ComponentGatherer > > > > def initialize() > > @@components =3D [] > > Dir.foreach( File.dirname( __FILE__ ) ){|x| > > next unless x =3D~ /component.rb$/i > > x.gsub!( ".rb", "" ) > > require "#{x}" > > @@components.push( x ) > > } > > end > > > > def components > > @@components.each{ |x| > > test =3D x.new() > > # Blah, blah, blah > > } > > end > > end > > > > > > Locating and requring the files seems to be working fine, it's when the > > component() call is made that I'm a bit lost. I have to > > *Component.rbfiles, they look like this: > > > > MyOtherComponent.rb > > -------------------------------- > > class MyOtherTestComponent > > > > attr :test > > > > def initialize() > > self.test =3D 2 > > end > > end > > > > The error I get from the components() method is: > > > > undefined method `new' for "MyOtherTestComponent":String > (NoMethodError) > > > > I understand what the error is saying, but I'm not sure how to call > new() on > > "x" above such that it returns an object of the requested class. Any > help > > is appreciated. > > > > Regards, > > > > Troy Denkinger > > > > If there is a way to map from the file name to the class name (in this > example, it would map "MyOtherComponent.rb" to "MyOtherTestComponent"), > then you can do this first, and then use const_get to get the class: > > x =3D "MyOtherComponent.rb" > x.gsub(/.rb$/, "") > x.gsub(/Component/, "TestComponent") > cl =3D Kernel.const_get x > obj =3D cl.new > > But it's sometimes difficult to enforce this filename/classname > consistency. > > I prefer something like this: > > http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/181735 > > It still uses const_get, but it wraps the component inside a module, so > that the global namespace doesn't get polluted, and you can query for > the class that was defined in a file without mucking around with the > file name. > > HTH. > > -- > vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407 > > ------=_Part_9484_13175311.1141409740618--