Skip to main content

Kernel.const_get

require 'set'

class Plugin
  # Keep the plugin list inside a set so we don't double-load plugins
  @plugins = Set.new

  def self.plugins
    @plugins
  end

  def self.register_plugins
    # Iterate over each symbol in the object space
    Object.constants.each do |klass|
      # Get the constant from the Kernel using the symbol
      const = Kernel.const_get(klass)
      # Check if the plugin has a super class and if the type is Plugin
      if const.respond_to?(:superclass) and const.superclass == Plugin
        @plugins << const
      end
    end
  end
end

class DogPlugin < Plugin

  def self.handle_command(cmd)
    p "Command received #{cmd}"
  end

end
class CatPlugin < Plugin

  def self.handle_command(cmd)
    p "Command received #{cmd}"
  end

end

Plugin.register_plugins

# Test that we can send a message to each plugin
Plugin.plugins.each do |plugin|
  plugin.handle_command('test')
end
    
"Command received test"
"Command received test"
=> #<Set: {DogPlugin, CatPlugin}>
    
require 'set'

module A
  class Plugin
    @plugins = Set.new

    class << self
      attr_reader :plugins
    end

    def self.register_plugins
      # Iterate over each symbol in the object space
      Object.constants.each do |klass|
        # Get the constant from the Kernel using the symbol
        const = Kernel.const_get(klass)
        # Check if the plugin has a super class and if the type is Plugin
        if const.respond_to?(:superclass) && (const.superclass == A::Plugin)
          @plugins << const
        end
      end
    end
  end
end

module A
  class MyAction < Plugin
    def self.handle_command(cmd)
      puts "Command received #{cmd}"
    end
   end
end

A::Plugin.register_plugins
A::Plugin.plugins.each do |plugin|
  plugin.handle_command('test')
end