{ Josh Rendek }

<3 Go & Kubernetes

A simple ruby plugin system

Jul 4, 2013 - 2 minutes

Let’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.

 1
 2class Plugin
 3  # Keep the plugin list inside a set so we don't double-load plugins
 4  @plugins = Set.new
 5
 6  def self.plugins
 7    @plugins
 8  end
 9
10  def self.register_plugins
11    # Iterate over each symbol in the object space
12    Object.constants.each do |klass|
13      # Get the constant from the Kernel using the symbol
14      const = Kernel.const_get(klass)
15      # Check if the plugin has a super class and if the type is Plugin
16      if const.respond_to?(:superclass) and const.superclass == Plugin
17        @plugins << const
18      end
19    end
20  end
21end

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 ).

1
2require './plugin'
3Dir["./plugins/*.rb"].each { |f| require f }
4Plugin.register_plugins
5
6# Test that we can send a message to each plugin
7Plugin.plugins.each do |plugin|
8  plugin.handle_command('test')
9end

This is a very simple but useful way to make a plugin system to componentize projects like a chat bot for IRC.

comments powered by Disqus