4

For example - If I have an application and I want to create an object that will be imported though a plugin, how would I go about writing that?

I've put together an example - It works as I'm intending; however I'm not sure if this is the 'conventional' way to go about it.

Is there a more efficient, or proper way to do this in Ruby?

start.rb

require './cloud.rb'

dir = 'plugins'
$LOAD_PATH.unshift(dir)
Dir[File.join(dir, "*.rb")].each {|file| require File.basename(file) }

mycloud = CloudProvider.descendants.first.new


mycloud.say('testing')

cloud.rb

class CloudProvider

  def self.descendants
    ObjectSpace.each_object(Class).select { |asdf| asdf < self }
  end
end

plugins/aws.rb

# This one inside plugins/
class AWS < CloudProvider
  def initialize

  end

  def say(val)
    puts val
  end
end
TJ Biddle
  • 6,024
  • 6
  • 40
  • 47
  • If your plugin is just something that implements an interface you specify, you shouldn't even have a base class. In Ruby, you don't need to declare interfaces (as you do in Java, eg). If an object responds to the methods of an interface, it implements them. – Jonah Aug 02 '13 at 06:38

1 Answers1

1

Jekyll is a widely used Ruby project that provides plugins. I like their approach a lot:

  1. Implement a base class that implements the basic functionality of your plugin (Jekyll has a few different types of classes you can inherit from).

  2. Clearly specify what methods a subclass will have to override to make the plugin work.

Then you can have your user dump all their plugins in a plugins directory and load all the files as you're doing now. This approach is built on solid OO concepts and it's very clean.

One suggestion: Ruby provides a inherited callback that you can use. This is much better than searching through all classes with asdf < self.

Vlad the Impala
  • 15,572
  • 16
  • 81
  • 124
  • Heh. I just realized I kept in 'asdf' - I originally found that line as 'klass' and was testing to see if it was a special keyword as I've seen it around. – TJ Biddle Aug 02 '13 at 05:56
  • Thanks! Went ahead and read through this now that I had a few spare minutes - Very clean approach! – TJ Biddle Aug 03 '13 at 00:40