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

 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.

comments powered by Disqus