From: ara.t.howard@... Date: 2006-08-02T07:02:23+09:00 Subject: Re: Strategies for autoloading ruby files On Wed, 2 Aug 2006, Luke Kanies wrote: > Hi all, > > Following up on my post about complicated problems, here's a much simpler > problem that I need to tackle. > > There are many parts of my framework that are extensible, and I want people > to be able to create extensions without modifying the core framework, akin > to how you don't have to specifically load each model and controller in > Rails. > > Is there a relatively standard way of doing that with Ruby? This is what > I'm doing in one of my projects, Facter[1]: > > # Now see if we can find any other facts > $:.each do |dir| > fdir = File.join(dir, "facter") > if FileTest.exists?(fdir) and FileTest.directory?(fdir) > Dir.glob("#{fdir}/*.rb").each do |file| > # Load here, rather than require, because otherwise > # the facts won't get reloaded if someone calls > # "loadfacts". Really only important in testing, > # but, well, it's important in testing. > begin > load file > rescue => detail > warn "Could not load %s: %s" % > [file, detail] > end > end > end > end > > I've tried further copying Rails by checking that loaded files create the > objects it seems they should create (e.g., here they should create a fact > named after the file), but users constantly complained about those warnings. > > Is this the best way? Any other recommended mechanisms? > > I'd actually like the autoloading to work either on-demand (e.g., look for > 'facter/myfact' if I ask for the 'myfact' fact), or load all of them right > now. > > Hmm. In fact, it'd be ideal if you could write a module that allows you to > register autoload paths (e.g., I'd use 'facter', 'puppet/type', > 'puppet/type/package', 'puppet/type/service', and lots more), and then just > have hooks into that module so that you could autoload all instances, or just > load a specific name. > > 1 - http://reductivelabs.com/projects/facter this may be helpful (or not! ;-)) http://codeforpeople.com/lib/ruby/dynaload/ i use it for plugins in my satellite processing system like so class PlugIn def self.inherited other Dynaload::export self, 'plugin' => true end end then plugins are written something like require 'plugin' class MyPlugIn < Plugin # # stuff # end then, assume that is saved in myplugin.rb, then i can do require 'dynaload' loaded = Dynaload::dynaload 'myplugin.rb' plugins = loaded.select{|klass, attributes| attributes['plugin'] == true} make sense? the reason it's at 0.0.0 is that it just worked for me - been using in production for a long time. cheers. -a -- we can never obtain peace in the outer world until we make peace with ourselves. - h.h. the 14th dali lama