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 8 1 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 class 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 20 end

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:

1 class DogPlugin < Plugin 2 3 def handle_command ( cmd ) 4 p "Command received #{ cmd } " 5 end 6 7 end

1 class CatPlugin < Plugin 2 3 def handle_command ( cmd ) 4 p "Command received #{ cmd } " 5 end 6 7 end

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

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