L
Luke Kanies
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
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