NAME
Context::Singleton - handles context specific singletons
DESCRIPTION
What is a context specific singleton?
As your workflow handles its tasks, granularity become finer and certain entities behaves like singletons.
Nice example is user id/object after successful authentication. Its value is constant for every function/method called after it is known but is unknown and can represents millions of users.
How does it differ from the multiton pattern?
Multiton is a set of singletons (global variables) whereas Context::Singleton provides context scope.
Doesn't local
already provide similar behaviour?
Context::Singleton doesn't provide only localized scope.
It provides immutability on scope and can build values based on dependencies. With dependency tracking it can rebuild them in inner scope in case their dependencies were modified.
EXPORTED FUNCTIONS
Terms
resource
Singleton idenfication, string, global.
recipe
Rule specifies how to build value
contrive 'resource' => ( ... );
There can be multiple recipes for building a singleton value
. The one with most relevant dependencies (those proclaimed in the deepest frame) will be used. If there are more available recipes, the first defined will be used.
Refer #contrive for more.
frame
Frame represents hierarchy.
Resource values are by default cached in the top-most frame providing all their dependencies.
Cached values are destroyed upon leaving context.
EXPORTED FUNCTIONS
Context singleton exports the following functions by default.
frame CODE
frame {
...;
}
Creates a new frame. Its argument behaves like a function and it returns its return value. It preserves list/scalar context when calling CODE.
proclaim resource => value, ...;
proclaim resource => value;
proclaim resource => value, resource2 => value2;
Define the value of a resource in the current context.
The resource's value in a given frame can be defined only once.
Returns the value of the last resource in the argument list.
deduce
my $var = deduce 'resource';
Makes and returns a resource value available in current frame.
If resource value is not available, it tries to build it using known recipes or looks into parent frames (using deepest = best).
load_path
load_path 'prefix-1', ...;
Evaluate all modules within given module prefix(es). Every prefix is evaluated only once.
contrive
Defines new receipt how to build resource value
contrive 'name' => (
class => 'Foo::Bar',
deduce => 'rule_object',
builder => 'new',
default => { rule_1 => 'v1', ... },
dep => [ 'rule_2', ... ],
dep => { param_a => 'rule_1', ... },
as => sub { ... },
value => 10,
);
- value => constant
-
Simplest rule, just constant value.
- as => CODEREF
-
Defines code used to build resource value. Dependencies are passed as arguments.
- builder => method_name
-
Specifies builder method name to be used by
class
ordeduce
. Defaults tonew
. - class => Class::Name
-
Calls the builder method with dependencies on the given class to build a value. Automatically creates a rule with the given class name using a default builder providing dynamic load.
Behaves essentially like
eval "use Class::Name"; Class::Name->$builder (@deps);
- deduce => rule_name
-
Calls the builder method (with dependencies) on the object available as a value of the given rule.
Behaves essentially like
my $object = deduce ('rule_name'); $object->$builder (@deps);
- default
-
Default values of dependencies. If used they are treated as deduced in root context but not stored nor cached anywhere.
- dep
-
Dependencies required to deduce this rule.
Two forms are recognized at the moment:
- ARRAYREF
-
List of required rules. Passed as a list to the builder function
- HASHREF
-
Hash values are treated as rule names. Passed as a list of named parameters to the builder function.
TUTORIAL
See short tutorial Context::Singleton::Tutorial