The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Curio::Factory - Definer, creator, provider, and holder of Curio objects.

SYNOPSIS

    my $factory = MyApp::Service::Cache->factory();

DESCRIPTION

The factory object contains the vast majority of Curio's logic. Each Curio class (Moo classes who consume Curio::Role) gets a single factory object created for them via "initialize" in Curio::Role.

Note that much of the example code in this documentation is based on the "SYNOPSIS" in Curio. Also when you see the term "Curio object" it is referring to instances of "class".

REQUIRED ARGUMENTS

class

    class => 'MyApp::Service::Cache',

The Curio class that this factory uses to instantiate Curio objects.

This is automatically set by "initialize" in Curio::Role.

OPTIONAL ARGUMENTS

does_registry

    does_registry => 1,
    resource_method_name => 'chi',

Causes the resource of all Curio objects to be automatically registered so that "find_curio" may function.

Defaults off (0), meaning "find_curio" will always return undef.

resource_method_name

    resource_method_name => 'chi',

The method name in the Curio class to retrieve the resource that it holds. A resource is whatever "thing" the Curio class encapsulates. In the case of the example in "SYNOPSIS" in Curio the resource is the CHI object which is accessible via the chi method.

It is still your job to create the method in the Curio class that this argument refers to, such as:

    has chi => ( is=>'lazy', ... );

This argument must be defined in order for fetch_resource and "does_registry" to work, otherwise they will have no way to know how to get at the resource object.

This defaults to the string resource.

installs_curio_method

    does_registry => 1,
    resource_method_name => 'chi',
    installs_curio_method => 1,

This causes a curio() method to be installed in all resource object classes. The method calls "find_curio" and returns it, allowing for reverse lookups from resource objects to curio objects.

"does_registry" must be set for this to function.

does_caching

    does_caching => 1,

When caching is enabled all calls to "fetch_curio" will attempt to retrieve from an in-memory cache.

Defaults off (0), meaning all fetch calls will return a new Curio object.

cache_per_process

    cache_per_process 1,

Some resource objects do not like to be created in one process and then used in others. When enabled this will add the current process's PID and thread ID (if threads are enabled) to the key used to cache the Curio object.

If either of these process IDs change then fetch will not re-use the cached Curio object from a different process and will create a new Curio object under the new process IDs.

Defaults to off (0), meaning the same Curio objects will be used by fetch across all forks and threads.

Normally the default works fine. Some CHI drivers need this turned on.

export_function_name

    export_function_name => 'myapp_cache',

The export function is exported when the the Curio class is imported, as in:

    use MyApp::Service::Cache;
    my $chi = myapp_cache( $key );

See also "always_export" and "export_resource".

always_export

    always_export => 1,

When enabled this causes the export function to be always exported.

    use MyApp::Service::Cache;

When this option is not set you must explicitly request that the export function be exported.

    use MyApp::Service::Cache qw( myapp_cache );

export_resource

    export_resource => 1,

Rather than returning the curio object this will cause the resource object to be returned by the export function. Requires that "resource_method_name" be set.

does_keys

    does_keys => 1,

Turning this on allows a key argument to be passed to "fetch_curio" and many other methods. Typically, though, you don't have to set this as you'll be using "add_key" which automatically turns this on.

By enabling keys this allows "fetch_curio", caching, resource registration, injecting, and anything else dealing with a Curio object to deal with multiple Curio objects based on the passed key argument.

Defaults to off (0), meaning the factory will only ever manage a single Curio object.

allow_undeclared_keys

    allow_undeclared_keys => 1,

When "fetch_curio", and other key-accepting methods are called, they normally throw an exception if the passed key has not already been declared with "add_key". By allowing undeclared keys any key may be passed, which can be useful especially if coupled with "key_argument".

Defaults to off (0), meaning keys must always be declared before being used.

default_key

    default_key => 'generic',

If no key is passed to key-accepting methods like "fetch_curio" then they will use this default key if available.

Defaults to no default key.

key_argument

    key_argument => 'connection_key',

When set, this causes an extra argument to be passed to the Curio class during object instantiation. The argument's key will be whatever you set key_argument to and the value will be the key used to fetch the Curio object.

You will still need to write the code in your Curio class to capture the argument, such as:

    has connection_key => ( is=>'ro' );

Defaults to no key argument.

default_arguments

    default_arguments => {
        arg => 'value',
        ...
    },

When set, these arguments will be used when creating new instances of the Curio class.

Any other arguments such as those provided by "add_key" and "key_argument" will overwrite these default arguments.

ATTRIBUTES

declared_keys

    my $keys = $factory->declared_keys();
    foreach my $key (@$keys) { ... }

Returns an array ref containing all the keys declared with "add_key".

METHODS

fetch_curio

    my $curio = $factory->fetch_curio();
    my $curio = $factory->fetch_curio( $key );

Returns a Curio object. If "does_caching" is enabled then a cached object may be returned.

fetch_resource

    my $resource = $factory->fetch_resource();
    my $resource = $factory->fetch_resource( $key );

Like "fetch_curio", but always returns a resource.

create

    my $curio = $factory->create( %extra_args );
    my $curio = $factory->create( $key, %extra_args );

Creates a new curio object with arguments gotten from "arguments". Extra arguments, which will take precedence, may also be passed.

arguments

    my $args = $factory->arguments();
    my $args = $factory->arguments( $key );

This method returns an arguments hashref that would be used to instantiate a new Curio object. You could, for example, use this to produce a base-line set of arguments, then sprinkle in some more, and make yourself a special mock object to be injected.

add_key

    $factory->add_key( $key, %arguments );

Declares a new key and turns "does_keys" on if it is not already turned on.

Arguments are optional, but if present they will be saved and used by "fetch_curio" when calling new() on "class".

alias_key

    $factory->alias_key( $alias_key => $real_key );

Adds a key that is an alias to a key that was declared with "add_key". Alias keys can be used anywhere a declared key can be used.

find_curio

    my $curio_object = $factory->find_curio( $resource );

Given a Curio object's resource this will return that Curio object for it.

This does a reverse lookup of sorts and can be useful in specialized situations where you have the resource, and you need to introspect back into the Curio object.

    # I have my $chi and nothing else.
    my $factory = MyApp::Service::Cache->factory();
    my $curio = $factory->find_curio( $chi );

This only works if you've enabled "does_registry", otherwise undef is always returned by this method.

inject

    $factory->inject( $curio_object );
    $factory->inject( $key, $curio_object );

Takes a curio object of your making and forces "fetch_curio" to return the injected object (or the injected object's resource). This is useful for injecting mock objects in tests.

The "create" method is a good way to make the mock curio object.

inject_with_guard

    my $guard = $factory->inject_with_guard(
        $curio_object,
    );
    
    my $guard = $factory->inject_with_guard(
        $key, $curio_object,
    );

This is just like "inject" except it returns an guard object which, when it leaves scope and is destroyed, will automatically "uninject".

uninject

    my $curio_object = $factory->uninject();
    my $curio_object = $factory->uninject( $key );

Removes the previously injected curio object, restoring the original behavior of "fetch_curio".

Returns the previously injected curio object.

injection

    my $curio_object = $factory->injection();
    my $curio_object = $factory->injection( $key );

Returns the injected curio object, or undef if none has been injected.

COPYRIGHT AND LICENSE

Copyright (C) 2019 Aran Clary Deltac

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.