Class: Module::Pluggable::Plugins
- Inherits:
-
Object
- Object
- Module::Pluggable::Plugins
- Includes:
- Enumerable
- Defined in:
- lib/module/pluggable.rb
Defined Under Namespace
Classes: ClassNotFoundError, NotInheritAbstractClassError, PluginsError
Instance Method Summary collapse
-
#[](klass_name) ⇒ Object
Get instance of
klass_name
plugin. -
#call(name, *args) ⇒ Object
Call
name
method of each plugins withargs
and returns Hash of the result and its plugin name. -
#each(&block) ⇒ Object
Iterates with plugin name and its instance.
-
#force_reload ⇒ Object
Unload all plugins and reload it.
-
#initialize(opts) ⇒ Plugins
constructor
A new instance of Plugins.
-
#load(klass_name) ⇒ Object
Load
klass_name
. -
#method_missing(name, *args) ⇒ Object
Undefined methods are delegated to each plugins.
-
#reload(klass_name = nil) ⇒ Object
Reload
klass_name
or load unloaded plugins or reload modified plugins. -
#unload(klass_name) ⇒ Object
Unload +klass_name.
Constructor Details
#initialize(opts) ⇒ Plugins
Returns a new instance of Plugins.
53 54 55 56 57 58 |
# File 'lib/module/pluggable.rb', line 53 def initialize(opts) @opts = opts @dir = Pathname.new(opts[:search_path]) @plugins = {} reload end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args) ⇒ Object
Undefined methods are delegated to each plugins. This is alias of call
162 163 164 |
# File 'lib/module/pluggable.rb', line 162 def method_missing(name, *args) call(name, *args) end |
Instance Method Details
#[](klass_name) ⇒ Object
Get instance of klass_name
plugin.
98 99 100 |
# File 'lib/module/pluggable.rb', line 98 def [](klass_name) @plugins[klass_name][:instance] if @plugins.key?(klass_name) end |
#call(name, *args) ⇒ Object
Call name
method of each plugins with args
and returns Hash of the result and its plugin name.
152 153 154 155 156 157 158 |
# File 'lib/module/pluggable.rb', line 152 def call(name, *args) ret = {} each do |k,v| ret[k] = v.send(name, *args) if v.respond_to?(name) end ret end |
#each(&block) ⇒ Object
Iterates with plugin name and its instance.
144 145 146 147 148 |
# File 'lib/module/pluggable.rb', line 144 def each(&block) @plugins.each do |k,v| yield k, v[:instance] end end |
#force_reload ⇒ Object
Unload all plugins and reload it.
137 138 139 140 141 |
# File 'lib/module/pluggable.rb', line 137 def force_reload call(:on_unload) @plugins.clear reload end |
#load(klass_name) ⇒ Object
Load klass_name
. The plugin is loaded in anonymous module not order to destroy the environments. And remember loaded time for reloading.
plugin filename must be interconversion with its class name. In this class, the conversion is do with file2klass
/klass2file
methods.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/module/pluggable.rb', line 67 def load(klass_name) return if @plugins.include?(klass_name) filename = klass2file(klass_name) mod = Module.new mod.module_eval(File.open("#{@opts[:search_path]}/#{filename}.rb") {|f| f.read}, filename) c = nil begin c = mod.const_get(klass_name) rescue NameError raise ClassNotFoundError.new("#{@opts[:search_path]}/#{filename} must include #{klass_name} class") end if !@opts[:base_class] || c < @opts[:base_class] @plugins[klass_name] = { :instance => c.new, :loaded => Time.now, } else raise NotInheritAbstractClassError.new("The class #{klass_name} must inherit #{@opts[:base_class]}") end @plugins[klass_name][:instance].on_load rescue NameError @plugins[klass_name][:instance].instance_variable_set(:@plugins, self) klass_name end |
#reload(klass_name = nil) ⇒ Object
Reload klass_name
or load unloaded plugins or reload modified plugins. returns [loaded, unloaded]
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/module/pluggable.rb', line 114 def reload(klass_name=nil) if klass_name unload(klass_name) load(klass_name) klass_name else loaded = [] unloaded = [] Dir.glob("#{@opts[:search_path]}/*.rb") do |f| klass_name = file2klass(File.basename(f, ".rb").sub(/^\d+/, "")) if @plugins.include?(klass_name) if File.mtime(f) > @plugins[klass_name][:loaded] loaded << reload(klass_name) end else loaded << reload(klass_name) end end [loaded, unloaded] end end |
#unload(klass_name) ⇒ Object
Unload +klass_name
103 104 105 106 107 108 |
# File 'lib/module/pluggable.rb', line 103 def unload(klass_name) if @plugins.key?(klass_name) @plugins[klass_name][:instance].on_unload rescue NameError @plugins.delete(klass_name) end end |