[Chicago-talk] undef and Moose types

Jonathan Rockway jon-chicagotalk at jrock.us
Fri Apr 29 22:36:45 PDT 2011

* On Fri, Apr 29 2011, Sean Blanton wrote:
> Yeah, the 'Maybe' works great, and thanks for pointing me to the doc.
> My ssh_builder looks like your safe_ssh, not sure what you meant. I
> have one &ssh_builder for all (86!) classes. If a new class wants an
> ssh connection, it consumes the 'SSH' role with the ssh attribute
> populated by &ssh_builder.

This means you want dependency injection.  Classes should *not* know how
to build things that they have; that's the job for some other part of
the program.

Bread::Board is a Moose-based module for dependency injection.  You can
write something like this:

    use Bread::Board;
    my $c = container 'MyApp' as {
        service 'ssh' => (
            class     => 'Net::SSH',
            lifecycle => 'Singleton', # if you want the same
                                      # instance each time

        service 'LogInAndDeleteEverything' => (
            class        => 'MyApp::Action::LogInAndDeleteEverything',
            dependencies => [ depends_on('ssh') ],

    my $action = $c->resolve( service => 'LogInAndDeleteEverything' );
    $action->execute; # everything is deleted

Your MyApp::Action::LogInAndDeleteEverything would look something like:

    package MyApp::Action::LogInAndDeleteEverything;
    use Moose;

    has 'ssh' => (
        is => 'ro',
        isa => 'Net::SSH',
        required => 1,

    sub execute { ... }

Bread::Board also has support for type mapping, so theoretically there
won't be much boilerplate even if you have 86 classes that all need the
'ssh' service.  I haven't used this feature much, however.

In addition to class injection, there is also block injection, where you
can use a coderef to build the instance.  Sometimes convenient.

It's also worth noting that services can have parameters and that you
can pass in args during "resolve", so if your code looked something

    has 'ssh' => ( ... as above ... );

    has 'chdir_to' => ( ... );

Your service could be changed to:

    service 'LogInAndDeleteEverything' => ( # remind me never to use such
                                            # a long name for an example!
        class        => 'MyApp::Action::LogInAndDeleteEverything',
        dependencies => [ depends_on('ssh') ],
        parameters   => { chdir_to => { default => '/' } },

Then, if you want to delete /etc, you would say:

    my $action = $c->resolve(
        service    => 'LogInAndDeleteEverything',
        parameters => { chdir_to => '/etc' },
    $action->execute; # BAI.

Anyway, Bread::Board is pretty simple and easy to hack on, so it should
be possible to do what you want without making a mess.

One more thing: you can make diagrams of your services and your


Finally, I used Bread::Board::Service as an example in the README here:



print just => another => perl => hacker => if $,=$"

More information about the Chicago-talk mailing list