# PODNAME: Bread::Board::Manual::Concepts::Typemap
# ABSTRACT: An overview of the typemapping feature
__END__
=pod
=head1 NAME
Bread::Board::Manual::Concepts::Typemap - An overview of the typemapping feature
=head1 VERSION
version 0.27
=head1 INTRODUCTION
A new (read: experimental) feature of Bread::Board is typemapped services.
These are services which are mapped to a particular type rather then just
a name. This feature has the potential to make obsolete a large amount of the
Bread::Board configuration by simply asking Bread::Board to figure things
out on its own. Here is a small example of how this works.
# define the classes making sure
# to specify required items and
# their types
{
package Stapler;
use Moose;
package Desk;
use Moose;
package Chair;
use Moose;
package Cubicle;
use Moose;
has 'desk' => ( is => 'ro', isa => 'Desk', required => 1 );
has 'chair' => ( is => 'ro', isa => 'Chair', required => 1 );
package Employee;
use Moose;
has [ 'first_name', 'last_name' ] => (
is => 'ro',
isa => 'Str',
required => 1,
);
has 'stapler' => ( is => 'rw', isa => 'Stapler', predicate => 'has_stapler' );
has 'work_area' => ( is => 'ro', isa => 'Cubicle', required => 1 );
}
# now create the container, and
# map the Employee type and ask
# Bread::Board to infer all the
# other relationships
my $c = container 'Initech' => as {
typemap 'Employee' => infer;
};
# now you can create new Employee objects
# by calling ->resolve with the type and
# supplying the required parameters (see
# below for details).
my $micheal = $c->resolve(
type => 'Employee',
parameters => {
first_name => 'Micheal',
last_name => 'Bolton'
}
);
my $cube = $micheal->work_area; # this will be a Cubicle object
$cube->desk; # this will be a Desk object
$cube->chair; # this will be a Chair object
$micheal->has_stapler; # this is false
# We can create another Employee object
# and this time we pass in the optional
# parameter for the non-required 'stapler'
# attribute
my $milton = $c->resolve(
type => 'Employee',
parameters => {
first_name => 'Milton',
last_name => 'Waddams',
stapler => Stapler->new
}
);
$milton->has_stapler; # this is true
In the above example, we created a number of Moose classes that had
specific required relationships. When we called C<infer> for the
B<Employee> object, Bread::Board figured out those relationships
and set up dependencies and parameters accordingly.
For the C<work_area> object, we saw the B<Cubicle> type and then
basically called C<infer> on the B<Cubicle> object. We then saw
the B<Desk> and B<Chair> objects and called C<infer> on those as well.
The result of this recursive inferrence was that the B<Employee>,
B<Cubicle>, B<Desk> and B<Chair> relationships were modeled in
Bread::Board as dependent services.
Bread::Board also took it one step further.
We were able to resolve the B<Cubicle>, B<Desk> and B<Chair> types
automatically because they were already defined by Moose as subtypes
of the I<Object> type. We knew that it could introspect those classes
and get more information. However, this was not the case with the
I<first_name> and I<last_name> attributes of the B<Employee> object.
In that case, we determined that we couldn't resolve those objects and
(because it was a top-level inferrence) instead turned them into required
parameters for the inferred B<Employee> service.
And lastly, with a top-level inferrence (not one caused by recursion)
Bread::Board will also look at all the remaining non-required attributes
and turn them into optional parameters. In this case we have a C<stapler>
attribute that is not required and so is listed as an optional parameter,
meaning that it is not required, but still subject to type checking.
=head1 CONCLUSION
This example should give a good basic overview of this feature and more
details can be found in the test suite (F<t/07*.t>). These show examples
of how to typemap roles to concrete classes and how to supply hints to
C<infer> to help Bread::Board figure out specific details.
As I mentioned above, this feature should be considered experimental
and we are still working out details and writing tests for it. Any
contributions are welcome.
=head1 AUTHOR
Stevan Little <stevan@iinteractive.com>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2013 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.
=cut