Skip to content

Instantly share code, notes, and snippets.

@nyarly
Created April 17, 2014 21:59
Show Gist options
  • Save nyarly/11013935 to your computer and use it in GitHub Desktop.
Save nyarly/11013935 to your computer and use it in GitHub Desktop.
module RoadForest
module Utility
class ClassRegistry
#Extend a module with this in order to make it the registrar for a
#particular purpose.
#The top of a class heirarchy will make "register" immediately available
#to subclasses. Otherwise, classes can say Module::registry.add(name,
#self)
#
module Registrar
def registry
@registry ||= ClassRegistry.new(self)
end
def register(name)
registrar.registry.add(name, self)
end
def get(name)
registrar.registry.get(name)
end
alias [] get
def all_names
registrar.registry.names
end
def map_classes(&block)
registrar.map_classes(&block)
end
def self.extended(mod)
(
class << mod; self; end
).instance_exec(mod) do |mod|
define_method :registrar do
mod
end
end
end
end
def initialize(registrar, purpose=nil)
if purpose.nil?
if registrar.respond_to?(:registry_purpose)
@purpose = registrar.registry_purpose
else
@purpose = registrar.name
end
else
@purpose = purpose
end
@classes = {}
end
def map_classes
names.map do |name|
yield get(name)
end
end
def add(name, klass)
@classes[name.to_sym] = klass
@classes[name.to_s] = klass
end
def names
@classes.keys.select{|key| key.is_a? Symbol}
end
def get(name)
@classes.fetch(name)
rescue KeyError
raise "No #@purpose class registered as name: #{name.inspect} (there are: #{names.inspect})"
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment