Bread:...ntainer(3pm)

πŸ“¦
version 0.37 Β· 3 versions
, in debian bookworm, debian trixie, ubuntu noble, ubuntu questing

πŸ’– Bread::Board::Container β€” the manual, but make it slay πŸ’–

okay so bestie, welcome to Bread::Board::Container from the User Contributed Perl Documentation section (manpage section 3pm, iykyk). this is the page about the thing that holds your stuff. and by stuff i mean services and other containers. let's get into it 🫢


✨ VERSION ✨

version 0.37 β€” that's the one, no cap.


🌈 SYNOPSIS 🌸

look at this gorgeous tree of containers, literally a whole kingdom:

use Bread::Board;
my $c = container MCP => as {
    container Users => as {
        service flynn => ...;
        service bradley => ...;
        service dillinger => ...;
    };

    container Programs => as {
        container Rebels => as {
            service tron => ...;
            service yori => ...;
            alias flynn => '/Users/flynn';
        };

        # nested container
        container Slaves => as {
            service sark => ...;
            service crom => ...;
        };
    };
};

or, alternatively, you can just do it directly, no builder needed:

# OR directly...
my $guardians => Bread::Board::Container->new( name => 'Guardians' );
$guardians->add_service(
    Bread::Board::ConstructorInjection->new(
        name => 'dumont',
        ...,
    )
);
$c->get_sub_container('Programs')->add_sub_container($guardians);
wait, the second block is written exactly as the original had it, my love β€” yes, my $guardians => is in there, we do not touch the code, we only admire it πŸ’…

πŸ¦‹ DESCRIPTION πŸ¦‹

so this class is the container for Bread::Board. a container is, bestie, a thing that contains services and other containers. that's it. that's the whole vibe.

every container and every service has a name, so you end up with a whole tree of named nodes β€” exactly like files and directories in a filesystem πŸ—‚οΈ. and every item can be referenced using a path β€” the deets live in Bread::Board::Traversable, go read it, it's iconic.


πŸŽ€ ATTRIBUTES πŸŽ€

🌸 name

read/write string, and it's required. every container needs a name, periodt. it's how you reference it when you go fetch it later.

πŸ’œ services

a hashref, constrained by Bread::Board::Container::ServiceList, mapping names to the services that live directly inside this container. every service you add here gets its parent set to this container. cute, right?

you can also pass an arrayref of services instead of a hashref β€” the keys will just be the names of the services. no stress.

bestie, you should probably use add_service and get_service to mess with this attribute instead of poking it directly. just saying. πŸ™ˆ

🧚 sub_containers

a hashref, constrained by Bread::Board::Container::SubContainerList, mapping names to the containers directly contained in this one. every container added here gets its parent set to this container. same energy.

arrayref works here too β€” pass one instead of a hashref and the keys become the names of the containers. ✨

again, add_sub_container and get_sub_container are your besties for this. modify it directly and that's on you πŸ’€

containers added here can be either a normal Bread::Board::Container or a Bread::Board::Container::Parameterized. both are welcome at the function, honestly.


πŸ‘‘ METHODS πŸ‘‘

🌟 add_service

$container->add_service($service);

drops a service into the services map, using its name as the key. simple, clean, slay.

🌟 get_service

my $service = $container->get_service($name);

hands you back a service by name. if there's no such service in the services map, you get undef. that's it.

🌟 has_service

if ($container->has_service($name)) { ... }

returns true if a service with that name exists in the services map, false otherwise.

🌟 has_services

if ($container->has_services) { ... }

returns true if the services map has literally any services in it, false if it's empty. vibe check on your map ✨

🌟 get_service_list

my @service_names = $container->get_service_list();

gives you the names of all the services hanging out in the services map.

🌟 add_sub_container

$container->add_sub_container($container);

puts a container into the sub_containers map, keyed by its name. nesting hours πŸͺ†

🌟 get_sub_container

my $container = $container->get_sub_container($name);

returns a container by name, or undef if there's no such container in the sub_containers map.

🌟 has_sub_container

if ($container->has_sub_container($name)) { ... }

true if a container with that name exists in sub_containers, false if not.

🌟 has_sub_containers

if ($container->has_sub_containers) { ... }

true if the sub_containers map contains any containers, false if it's empty.

🌟 get_sub_container_list

my @container_names = $container->get_sub_container_list();

returns the names of all the containers present in the sub_containers map. all of them. the whole roster 🫢

🌟 add_type_mapping_for

$containers->add_type_mapping_for( $type_name, $service );

adds a mapping from a Moose type to a service. so whenever we try to resolve that type, we'll use that service to instantiate it. matchmaker energy, honestly πŸ’˜

🌟 get_type_mapping_for

my $service = $container->get_type_mapping_for( $type_name );

returns the service you'd use to instantiate the given type name.

Important, bestie, listen up: if a mapping for the exact type can't be found, but a mapping for a subtype of it can, you get the subtype one instead. yes really.
package Superclass { use Moose };
package Subclass { use Moose; exends 'Superclass' };

$c->add_type_mapping_for(
 'Subclass',
 Bread::Board::ConstructorInjection->new(name=>'sc',class=>'Subclass'),
);
my $o = $c->get_type_mapping_for('Superclass')->get;

$o is an instance of Subclass. and if there's more than one sub-type mapped? you get a random one. which is, and i quote the original, probably a bad idea. πŸ’€ noted. we love honesty.

🌟 has_type_mapping_for

if ($container->has_type_mapping_for( $type_name )) { ... }

true if we have a service defined to instantiate the given type name β€” but go reread the note on get_type_mapping_for about subtype mapping, because that caveat applies here too πŸ‘€

🌟 resolve

my $object = $container->resolve(service=>$service_name);
my $object = $container->resolve(service=>$service_name,parameters=>\%p);

give it a service name and it fetches the service, then calls get on it β€” optionally passing along the parameters you handed over.

my $object = $container->resolve(type=>$type);
my $object = $container->resolve(type=>$type,parameters=>\%p);

give it a type name instead and it uses get_type_mapping_for to grab the service, then calls get on it, optionally with your parameters. and if the instance that comes back isn't the type you expected? the method will die. dramatic, but fair 😭


πŸ“ AUTHOR πŸ“

Stevan Little <stevan@iinteractive.com> β€” thank you king πŸ‘‘


πŸ’€ BUGS πŸ’€

please report any bugs or feature requests on the bugtracker website:

https://github.com/stevan/BreadBoard/issues

when you submit a bug or a request, pretty please include a test-file, or a patch to an existing test-file, that shows off the bug or the feature you want. receipts, bestie, receipts 🧾


this software is copyright (c) 2019, 2017, 2016, 2015, 2014, 2013, 2011, 2009 by Infinity Interactive.

this is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. free is free, and we love that for it 🫢


and that's the whole page, bestie! πŸ’– this one's brought to you by perl v5.36.0, dated 2022-12-12, and it's giving legendary documentation. go build your container tree, you're gonna eat πŸŒΈβœ¨πŸŽ€πŸ¦‹

πŸ“¦ where this page comes from