Module: ClassX::Pluggable

in your context class.

  require 'classx'
  require 'classx/pluggable'
  class YourApp
    include ClassX
    include ClassX::Pluggable

    def run
      call_event("SETUP", {})
      # you app
      call_event("TEARDOWN", {})
    end

  end

in your plugin class

  require 'classx'
  require 'classx/pluggable'
  class YourApp
    class Plugin
      include ClassX
      include ClassX::Pluggable::Plugin

      class SomePlugin < Plugin
        def register
          add_event("SETUP", :on_setup)
        end

        def on_setup param
          # param is Hash
          # hooked setup
        end
      end
    end
  end

Child modules and classes

Module ClassX::Pluggable::ClassMethods
Module ClassX::Pluggable::Plugin
Module ClassX::Pluggable::Util
Class ClassX::Pluggable::MockContext
Class ClassX::Pluggable::PluginLoadError

Public Instance Methods


add_event (name, plugin, meth)

register plugin and method to hook point.

    # File lib/classx/pluggable.rb, line 72
72:     def add_event name, plugin, meth
73:       name = name.to_s
74:       if self.check_events && !self.events.include?(name)
75:         raise "#{name.inspect} should be declared before call add_event. not in #{self.events.inspect}"
76:       else
77:         self.__classx_pluggable_events_of[name] ||= []
78:       end
79:       self.__classx_pluggable_events_of[name] << { :plugin => plugin, :method => meth }
80:     end

call_event (name, *args)

invoke registered event of name with args. and return array of result each callback.

     # File lib/classx/pluggable.rb, line 117
117:     def call_event name, *args
118:       name = name.to_s
119:       if events = self.__classx_pluggable_events_of[name]
120:         events.map do |event|
121:           event[:plugin].__send__(event[:method], *args)
122:         end
123:       else
124:         []
125:       end
126:     end

call_event_around (name, *args, &block)

invoke registered event of BEFORE_xxxx and yield block and invoke hook AFTER_xxxx.

     # File lib/classx/pluggable.rb, line 129
129:     def call_event_around name, *args, &block
130:       name = name.to_s
131:       around_name = "AROUND_#{name}"
132: 
133:       call_event("BEFORE_#{name}", *args)
134:       if events = self.__classx_pluggable_events_of[around_name]
135:         procs = []
136:         procs << block
137:         index = 0
138:         nested_proc = events.inject(block) {|bl, event| proc { event[:plugin].__send__(event[:method], *args, &bl ) } }
139:         nested_proc.call
140:       end
141:       call_event("AFTER_#{name}", *args)
142:     end

load_component (type, hash)

     # File lib/classx/pluggable.rb, line 106
106:     def load_component type, hash
107:       component = OpenStruct.new(hash.dup)
108:       mod = self.class.component_class_get(type, component.module, { :plugin_dir => self.plugin_dir })
109:       component.config ||= {}
110:       component.config[:context] = self
111:       instance = mod.new(component.config)
112:       instance.register
113:       logger.debug("ClassX::Pluggable: loaded #{type} #{component.module}, config=#{instance.inspect}")
114:     end

load_components (type, components)

if you customize Plugin name space. you can use this instead of load_plugins.

 app.load_components('engine', [
    { :module => "YourApp::Engine::Foo", :confiig => { :some_config => "foo"} },
    { :module => "+Bar", :confiig => { } }, # It's same meaning of YourApp::Engine::Bar
 ])
     # File lib/classx/pluggable.rb, line 100
100:     def load_components type, components
101:       components.each do |component|
102:         load_component type, component
103:       end
104:     end

load_plugins (plugins)

load plugins.

  app.load_plugins([
    { :module => "YourApp::Plugin::Foo", :confiig => { :some_config => "foo"} },
    { :module => "+Bar", :confiig => { } }, # It's same meaning of YourApp::Plugin::Bar
  ])
    # File lib/classx/pluggable.rb, line 89
89:     def load_plugins plugins
90:       load_components("plugin", plugins)
91:     end