A simple ruby plugin system
Jul 4, 2013 - 2 minutesLet’s start out with a simple directory structure:
1.
2├── plugin.rb
3├── main.rb
4└── plugins
5 ├── cat.rb
6 └── dog.rb
7
81 directory, 3 files
All the plugins we will use for our library will be loaded from plugins
. Now lets make a simple
Plugin
class and register our plugins.
1class Plugin
2 # Keep the plugin list inside a set so we don't double-load plugins
3 @plugins = Set.new
4
5 def self.plugins
6 @plugins
7 end
8
9 def self.register_plugins
10 # Iterate over each symbol in the object space
11 Object.constants.each do |klass|
12 # Get the constant from the Kernel using the symbol
13 const = Kernel.const_get(klass)
14 # Check if the plugin has a super class and if the type is Plugin
15 if const.respond_to?(:superclass) and const.superclass == Plugin
16 @plugins << const
17 end
18 end
19 end
20end
We’ve now made a simple class that will contain all of our plugin data when we call register_plugins
.
Now for our Dog and Cat classes:
1class DogPlugin < Plugin
2
3 def handle_command(cmd)
4 p "Command received #{cmd}"
5 end
6
7end
1class CatPlugin < Plugin
2
3 def handle_command(cmd)
4 p "Command received #{cmd}"
5 end
6
7end
Now combine this all together in one main entry point and we have a simple plugin system that lets us
send messages to each plugin through a set method ( handle_command
).
1require './plugin'
2Dir["./plugins/*.rb"].each { |f| require f }
3Plugin.register_plugins
4
5# Test that we can send a message to each plugin
6Plugin.plugins.each do |plugin|
7 plugin.handle_command('test')
8end
This is a very simple but useful way to make a plugin system to componentize projects like a chat bot for IRC.