Something like this one?
It has additional features like ability to load plugins from other plugins
by saying ‘require “”’ in the plugin’s code. Note <> in
require’s argument. Another feature is correct reporting of errors in
loaded plugin (not ‘Error in eval…’ but ‘Error in foo.rb:12345’).
------------------------------------------------------------------------------------------
···
On Thu, Mar 06, 2003 at 11:04:42PM +0900, Eugene Scripnik wrote:
Is there require method implementaion, which loads library in the
specified module context.
I want to store the classes with same name but different functionality
in one ruby process. So modules are the right thing I think.
Plugin loader interface
The content of this file is available under GNU LGPL
module Plugin
# Instantiates a new module mod_name under Plugin hierarchy which incapsulates requested plugin
# code from file_name source file.
def self.instantiate(mod_name, file_name)
# Create new module and set a proper binding information for it
# If you change the code below, adjust number of skipped lines appropriately.
# Line with #{File.open(“#{file_name}”, “r”){|f| f.read}} is treated as ‘line #1’
# The third argument to module_eval must contain a negative offset of ‘module #{mod_name}’
# from ‘line #1’. If you keep this as is, you’ll see meaningful error messages which will
# point to proper positions in your plugins if something wrong will happen
begin
mod = module_eval(<<EOF, file_name, -13 )
module #{mod_name}
class <<self
def require (amodule)
if amodule =~ /^<([^>]+)>/
fmod = ::PluginLoader.registry[$1]
if not (fmod.class === Module)
fmod = ::PluginLoader.registry.require(amodule)
end
else
Kernel.require amodule
end
end
end
#{File.open("#{file_name}", "r"){|f| f.read}}
self
end
EOF
rescue Exception => err
log 1, “Syntax Error in plugin #{mod_name}, #{file_name}, not loading”
STDERR.puts “Syntax Error in plugin #{mod_name}, #{file_name}, not loading:”
STDERR.puts “#{err.message}”
mod = false
end
return mod
end
end
module PluginLoader
class Registry < Hash
def initialize(plugin_path)
@plugin_path = plugin_path
end
def require(plugin)
if plugin =~ /^<([^>]+)>/
amodule = $1
return self[amodule] if self[amodule].class === Module
mod_name = amodule.to_s.gsub(/\//,"_").gsub(/\.(rb|so)/,"").capitalize
@plugin_path.each do |path|
[".rb", ".so", ""].each do |ext|
file_name = "#{path}/#{amodule}#{ext}"
if FileTest.file?(file_name)
mod = ::Plugin.instantiate(mod_name, file_name)
self[amodule] = mod if mod
return mod
end
end
end
else
Kernel.require plugin
end
end
end
class <<self
attr_reader :registry
def init_plugins(*path)
@registry = Registry.new(path)
end
def load_plugins(*plugins)
result = false
plugins.each do |plugin|
if @registry[plugin] || (@registry.require("<#{plugin}>").class === Module)
result = true
else
result = false
end
end
result
end
# Form list of loaded plugins
def list_plugins
PluginLoader.registry.values
end
end
end
--------------------------------------------------------------------------------------------
–
/ Alexander Bokovoy
One does not thank logic.
– Sarek, “Journey to Babel”, stardate 3842.4