Pluggability is a mixin module that turns an including class into a
factory for its derivatives, capable of searching for and loading them
by name. This is useful when you have an abstract base class which
defines an interface and basic functionality for a part of a larger
system, and a collection of subclasses which implement the interface for
different underlying functionality.
An example of where this might be useful is in a program which generates
output with a 'driver' object, which provides a unified interface but
generates different kinds of output.
First the abstract base class, which is extended with Pluggability:
# in mygem/driver.rb:
require 'pluggability'
require 'mygem' unless defined?( MyGem )
class MyGem::Driver
extend Pluggability
plugin_prefixes "drivers", "drivers/compat"
end
We can have one driver that outputs PDF documents:
# mygem/drivers/pdf.rb:
require 'mygem/driver' unless defined?( MyGem::Driver )
class MyGem::Driver::PDF < Driver
...implementation...
end
and another that outputs plain ascii text:
#mygem/drivers/ascii.rb:
require 'mygem/driver' unless defined?( MyGem::Driver )
class MyGem::Driver::ASCII < Driver
...implementation...
end
Now the driver is configurable by the end-user, who can just set
it by its short name:
require 'mygem'
config[:driver_type] #=> "pdf"
driver = MyGem::Driver.create( config[:driver_type] )
driver.class #=> MyGem::Driver::PDF
# You can also pass arguments to the constructor, too:
ascii_driver = MyGem::Driver.create( :ascii, :columns => 80 )