Bolts::Role::Initializer - Give components some control over their destiny


version 0.143171


    package MyApp::Thing;
    use Moose;

    use MyApp::Bag;

    has init_locator => (
        is          => 'rw',
        does        => 'Bolts::Role::Locator',
        lazy        => 1,
        builder     => '_build_init_locator',

    sub _build_init_locator { MyApp::Bag->new }

    with 'Bolts::Role::Initializer';

    has foo => (
        is          => 'rw',
        isa         => 'MyApp::Foo',
        traits      => [ 'Bolts::Initializer' ],

    # Later...
    use Bolts::Util qw( bolts_init );
    my $thing = MyApp::Thing->new(
        foo => bolts_init('path', 'to', 'foo'),


While IOC provides an elegant way to decouple your objects and such, it is sometimes convenient to give objects more control over their setup. This role grants your class a special initializer method that can be used by initializer attributes, which can automatically find their values using an associated Bolts::Role::Locator object.

For example, it can take a call like this:

    my $thing = MyApp::Thing->new(
        foo => $locator->acquire('path', 'to', 'foo'),

to this:

    my $thing = MyApp::Thing->new(
        foo => bolts_init('path', 'to', 'foo'),

The caller no longer has to know anything about the $locator, just a common path within. Perhaps an even better way would be to move the initialization of MyApp::Thing into the locator to manage it's life cycle, scope, etc., but sometimes this is more convenient or practical or even possible.

Any attribute you want to have initialized this way should be tagged with the Bolts::Initializer trait, which is defined in Bolts::Meta::Attribute::Trait::Initializer. This trait modifies the attribute so that it may be initialized either by the actual value without an initializer or by looking up a value within the "init_locator" of the object if given an initializer (a Bolts::Meta::Initializer object, usually gotten by calling "bolts_init" in Bolts::Util).

Caution: This is slightly messy with bits and pieces spread out a bit more than I like. I might reorganize these pieces a bit in the future if I can find a better way to do it.



    my $locator = $self->init_locator;

This method takes no arguments and must return an object that does Bolts::Role::Locator.



    my $value = $self->initialize_value(@path, \%params);

This is used to perform acquisition with the initializer object. This is just delegated to the acquire method of "init_locator".


Andrew Sterling Hanenkamp <>


This software is copyright (c) 2014 by Qubling Software LLC.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.