kigster / registry

For dirt simple plugin architecture

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Build Status Code Climate Test Coverage Issue Count

Registry — Simple Factory Pattern Ruby Library

registry is used to mix into a super class that has many or multiple implementations via subclasses.

This has been described as a factory pattern, John Barton describes 'registry' as a "meta-programming method factory".

A good example of this is a parser, you might have a parser for json and another for yml. Register your sub classes to handle certain labels or descriptions, then let the super class decide weather the message you send it can be handled or not.

Usage

Subclassing

A simple set of parsers:

require 'registry'

class Parser
  extend Registry
end

class Json < Parser
  identifier :json, :javascript
  
  def self.parse(source)
    JSON.load(source)
  end
end

class Yaml < Parser
  identifier :yaml, :yml
  
  def self.parse(source)
    YAML.load(source)
  end
end

Look for your the json parser

Parser.for(:json).parse(content)

Or the Yaml parser. Notice it also uses its class name as an identifier

Parser.for(:yaml).parse(content)

There is no parser for XML, this will raise a Registry::NotRegistered exception

Parser.for(:xml).parse(content)

Perhaps you'd like to call methods on the matching parser with a block? You can!

@content = '{"name":"Bobby"}'
Parser.for(:json) do
  parse(@content)
end
# => { 'name' => 'Bobby' }

Lookup Methods

For every key stored in the registry, a new method is automatically created on the superclass (the class extending the Registry module).

So the following is entirely legal and allowed:

Parser.yaml.parse(content)

The #register Method

Instead of creating a class hierarchy, you can store important things in the registry by adding them with a #register method:

An alternative to subclassing, this method allows passing arbitrary structures as an item, keyed by the :keys array.

As an example, consider a CacheManager class:

class CacheManager
  extend Registry
end

@content = '{ "name":"John Snow"}'
# Using the *args syntax:
CacheManager.register(:one, :two, :three, JSONs.load(@content))

# Using the **opts syntax:
CacheManager.register(keys: [:one, :two, :three], item: JSON.load(@content))

# Mixing the two, etc.s 
CacheManager.register(:one, :two, :three, item: JSON.load(@content))

# Then:
CacheManager.one['name'] # => "John Snow"

Installation

gem install registry 

Note on Patches/Pull Requests

  • Fork the project.
  • Make your feature addition or bug fix.
  • Add tests for it. This is important so I don't break it in a future version unintentionally.
  • Commit, do not mess with rakefile, version, or history. If you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull.
  • Send me a pull request. Bonus points for topic branches.

Copyright

Copyright (c) 2009 Ben Schwarz. See LICENSE for details.

Contributors

About

For dirt simple plugin architecture

License:Other


Languages

Language:Ruby 100.0%