From: ES Date: 2005-02-20T07:07:15+09:00 Subject: Re: Dynamically loading and executing within a new module? On 2/19/2005, "Lloyd Zusman" wrote: >I'm not sure what would be the best way to accomplish the following in >ruby: > >I'm writing a program that periodically looks for files in a certain >directory. If it finds new ones, I want it to ... > >1. Dynamically create a new module whose name is based somehow upon the > name of the file. > >2. Do a Kernel#load on the file within this newly created module. > >3. Invoke a method called #init that is defined in this file (assuming > that this method is actually defined), and do the invocation within > the context of that newly-created module. > >For example, suppose my directory contains the following files: > > foo.module > ---------- > def init > puts "invoking #init within #{self}" > end > > bar.module > ---------- > def init > puts "invoking #init within #{self}" > end > >When my program encounters the "foo.module" file, I'd like it to do the >following: > > - create a module called Foo (the name of the file with ".module" > stripped off and the first letter capitalized) ... or maybe > SomethingElse::Foo, to avoid collisions with existing packages > > - do a load() of the "foo.module" file within the context of this > newly created Foo module (or SomethingElse::Foo module) > > - check to see if the #init method is now defined within the > Foo module; if so, invoke that as a class method within the > context of that module (i.e., as if it were invoked like > Foo#init); this should cause the following message to > print: > > invoking #init within Foo > >What is the recommended way for accomplishing all this within Ruby? If you don't just want to write an actual module and then call its #init, you could do something like this. Somewhat pseudo: Thread.new do if fname mod = eval fname.capitalize data = File.new(fname, 'r') do |f| f.read end mod.module_eval data mod.send :init, args # ... end end Or sumptin :) > Lloyd Zusman E