NAME¶
Bread::Board::Manual::Concepts::Typemap - An overview of the typemapping feature
VERSION¶
version 0.29
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 "infer" for the
Employee object, Bread::Board figured out those relationships and set
up dependencies and parameters accordingly.
For the "work_area" object, we saw the
Cubicle type and then
basically called "infer" on the
Cubicle object. We then saw
the
Desk and
Chair objects and called "infer" on those
as well. The result of this recursive inferrence was that the
Employee,
Cubicle,
Desk and
Chair relationships were modeled in
Bread::Board as dependent services.
Bread::Board also took it one step further.
We were able to resolve the
Cubicle,
Desk and
Chair types
automatically because they were already defined by Moose as subtypes of the
Object type. We knew that it could introspect those classes and get
more information. However, this was not the case with the
first_name
and
last_name attributes of the
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
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 "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.
CONCLUSION¶
This example should give a good basic overview of this feature and more details
can be found in the test suite (
t/07*.t). These show examples of how
to typemap roles to concrete classes and how to supply hints to
"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.
AUTHOR¶
Stevan Little <stevan@iinteractive.com>
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.