Module: AmberVM::PluginHost

Included in:
Classes, Functions, Languages
Defined in:
lib/amber/plugin.rb

Overview

PluginHost

$Id: plugin.rb 255 2008-09-21 16:25:44Z murphy $

A simple subclass plugin system.

Example:
  class Generators < PluginHost
    plugin_path 'app/generators'
  end

  class Generator
    extend Plugin
    PLUGIN_HOST = Generators
  end

  class FancyGenerator < Generator
    register_for :fancy
  end

  Generators[:fancy]  #-> FancyGenerator
  # or
  AmberVM.require_plugin 'Generators/fancy'

Constant Summary collapse

PluginNotFound =

Raised if Encoders::[] fails because:

  • a file could not be found

  • the requested Encoder is not registered

Class.new Exception
HostNotFound =
Class.new Exception
PLUGIN_HOSTS =
[]
PLUGIN_HOSTS_BY_ID =

dummy hash

{}

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(mod) ⇒ Object

Adds the module/class to the PLUGIN_HOSTS list.



71
72
73
# File 'lib/amber/plugin.rb', line 71

def extended mod
  PLUGIN_HOSTS << mod
end

.host_by_id(host_id) ⇒ Object

Find the PluginHost for host_id.



81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/amber/plugin.rb', line 81

def host_by_id host_id
  unless PLUGIN_HOSTS_BY_ID.default_proc
    ph = Hash.new do |h, a_host_id|
      for host in PLUGIN_HOSTS
        h[host.host_id] = host
      end
      h.fetch a_host_id, nil
    end
    PLUGIN_HOSTS_BY_ID.replace ph
  end
  PLUGIN_HOSTS_BY_ID[host_id]
end

.included(mod) ⇒ Object

Warns you that you should not #include this module.



76
77
78
# File 'lib/amber/plugin.rb', line 76

def included mod
  warn "#{name} should not be included. Use extend."
end

Instance Method Details

#[](id, *args, &blk) ⇒ Object Also known as: load

Returns the Plugin for id.

Example:

yaml_plugin = MyPluginHost[:yaml]


48
49
50
51
52
53
54
# File 'lib/amber/plugin.rb', line 48

def [] id, *args, &blk
  plugin = validate_id(id)
  begin
    plugin = plugin_hash.[] plugin, *args, &blk
  end while plugin.is_a? Symbol
  plugin
end

#default(id = nil) ⇒ Object

Define the default plugin to use when no plugin is found for a given id.

See also map.

class MyColorHost < PluginHost
  map :navy => :dark_blue
  default :gray
end


142
143
144
145
146
147
148
149
# File 'lib/amber/plugin.rb', line 142

def default id = nil
  if id
    id = validate_id id
    plugin_hash[nil] = id
  else
    plugin_hash[nil]
  end
end

#has?(id) ⇒ Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/amber/plugin.rb', line 64

def has? id
  plugin_hash.has_key? validate_id(id)
end

#host_idObject

The host’s ID.

If PLUGIN_HOST_ID is not set, it is simply the class name.



108
109
110
111
112
113
114
# File 'lib/amber/plugin.rb', line 108

def host_id
  if self.const_defined? :PLUGIN_HOST_ID
    self::PLUGIN_HOST_ID
  else
    name
  end
end

#inspectObject

Makes a map of all loaded plugins.



182
183
184
185
186
187
188
# File 'lib/amber/plugin.rb', line 182

def inspect
  map = plugin_hash.dup
  map.each do |id, plugin|
    map[id] = plugin.to_s[/(?>\w+)$/]
  end
  "#{name}[#{host_id}]#{map.inspect}"
end

#listObject

Returns an array of all .rb files in the plugin path.

The extension .rb is not included.



173
174
175
176
177
178
179
# File 'lib/amber/plugin.rb', line 173

def list
  Dir[path_to('*')].select do |file|
    File.basename(file)[/^(?!_)\w+\.rb$/]
  end.map do |file|
    File.basename file, '.rb'
  end
end

#load_allObject

Loads all plugins using list and load.



38
39
40
41
42
# File 'lib/amber/plugin.rb', line 38

def load_all
  for plugin in list
    load plugin
  end
end

#map(hash) ⇒ Object

Map a plugin_id to another.

Usage: Put this in a file plugin_path/_map.rb.

class MyColorHost < PluginHost
  map :navy => :dark_blue,
    :maroon => :brown,
    :luna => :moon
end


125
126
127
128
129
130
131
# File 'lib/amber/plugin.rb', line 125

def map hash
  for from, to in hash
    from = validate_id from
    to = validate_id to
    plugin_hash[from] = to unless plugin_hash.has_key? from
  end
end

#plugin_hashObject

A Hash of plugion_id => Plugin pairs.



166
167
168
# File 'lib/amber/plugin.rb', line 166

def plugin_hash
  @plugin_hash ||= create_plugin_hash
end

#plugin_path(*args) ⇒ Object

The path where the plugins can be found.



97
98
99
100
101
102
103
# File 'lib/amber/plugin.rb', line 97

def plugin_path *args
  unless args.empty?
    @plugin_path = File.expand_path File.join(*args)
    load_map
  end
  @plugin_path or raise 'No plugin_path given for %p %p' % [args, self]
end

#register(plugin, *ids) ⇒ Object

Every plugin must register itself for one or more ids by calling register_for, which calls this method.

See Plugin#register_for.



155
156
157
158
159
160
161
162
163
# File 'lib/amber/plugin.rb', line 155

def register plugin, *ids
  for id in ids
    unless id.is_a? Symbol
      raise ArgumentError,
        "id must be a Symbol, but it was a #{id.class}"
    end
    plugin_hash[validate_id(id)] = plugin
  end
end

#require_helper(plugin_id, helper_name) ⇒ Object



59
60
61
62
# File 'lib/amber/plugin.rb', line 59

def require_helper plugin_id, helper_name
  path = path_to File.join(plugin_id, helper_name)
  require path
end