Class: Poro::ContextFactories::NamespaceFactory
- Inherits:
-
Poro::ContextFactory
- Object
- Poro::ContextFactory
- Poro::ContextFactories::NamespaceFactory
- Defined in:
- lib/poro/context_factories/namespace_factory.rb
Overview
The NamespaceFactory uses the module namespace of the class to determine which factory should be used to create a class instance.
On initialization, the default factory should be set. Until other factories are registerd, all classes will recieve contexts created by this factory.
Other factories can be registered against various namespaces. Namespaces are given as a string and are evaluated from the bottom up. For example, if a factory is registered against the class Foo::Bar, then Foo::Bar and Foo::Bar::Baz would each recieve contexts created via that factory, while contexts registered against Foo::Zap would use the default context.
Defined Under Namespace
Classes: CacheNode
Instance Method Summary collapse
-
#fetch_factory(namespace = '') ⇒ Object
Fetches the factory for a given namespace.
-
#initialize(default_factory = nil) {|_self| ... } ⇒ NamespaceFactory
constructor
Initialize this namespace factory instance with the given default factory.
-
#register_factory(factory, namespace = '') ⇒ Object
Registers a factory for a given namespace, given by a string.
Methods inherited from Poro::ContextFactory
#context_managed_class?, #fetch, has_instance?, instance, instance=
Constructor Details
#initialize(default_factory = nil) {|_self| ... } ⇒ NamespaceFactory
Initialize this namespace factory instance with the given default factory. Use register_factory
to add more kinds of factories to this app.
If given a block, it is yielded self for further configuration. This departs slightly from the standard of yielding a Class or Class and Context for configuration, but as this is more useful for practicle applications. (It also doesn’t configure a context itself, so giving separate blocks to the sub-factories given to it is more appropriate.
27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/poro/context_factories/namespace_factory.rb', line 27 def initialize(default_factory=nil) @root_node = CacheNode.new @root_node.factory = default_factory yield(self) if block_given? super() do |klass| factory = self.fetch_factory(klass) factory.nil? ? nil : factory.fetch(klass) end end |
Instance Method Details
#fetch_factory(namespace = '') ⇒ Object
Fetches the factory for a given namespace.
This grabs the factory for the most specific matching namespace.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/poro/context_factories/namespace_factory.rb', line 67 def fetch_factory(namespace='') namespace_stack = namespace.to_s.split('::') lookup_block = lambda do |namespace_stack, last_seen_factory, node| last_seen_factory = node.factory || last_seen_factory if( namespace_stack.length == 0 ) last_seen_factory elsif( !(node.children.include?(namespace_stack[0])) ) last_seen_factory else name, *rest = namespace_stack lookup_block.call(rest, last_seen_factory, node.children[name]) end end return lookup_block.call(namespace_stack, nil, @root_node) end |
#register_factory(factory, namespace = '') ⇒ Object
Registers a factory for a given namespace, given by a string. If a factory is already registered for this namespace, it overrides it.
This registers the given factory not only for this namespace, but for any sub-namespaces that haven’t been specifically overriden. Sub-namespace overrides can be registered either before or after the namespace it overrides.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/poro/context_factories/namespace_factory.rb', line 45 def register_factory(factory, namespace='') namespace_stack = namespace.to_s.split('::') parse_block = lambda do |factory, namespace_stack, node| if( namespace_stack.length == 0 ) node.factory = factory else name, *rest = namespace_stack child_node = node.children[name] || CacheNode.new node.children[name] = child_node parse_block.call(factory, rest, child_node) end end parse_block.call(factory, namespace_stack, @root_node) return factory end |