1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
package MooseX::Bread::Board::Meta::Role::Attribute;
use Moose::Role;
use Bread::Board::Types;
use MooseX::Bread::Board::BlockInjection;
use MooseX::Bread::Board::ConstructorInjection;
use MooseX::Bread::Board::Literal;
has class => (
is => 'ro',
isa => 'Str',
predicate => 'has_class',
);
has block => (
is => 'ro',
isa => 'CodeRef',
predicate => 'has_block',
);
# has_value is already a method
has literal_value => (
is => 'ro',
isa => 'Str|CodeRef',
init_arg => 'value',
predicate => 'has_literal_value',
);
has lifecycle => (
is => 'ro',
isa => 'Str',
predicate => 'has_lifecycle',
);
has dependencies => (
is => 'ro',
isa => 'Bread::Board::Service::Dependencies',
coerce => 1,
predicate => 'has_dependencies',
);
after attach_to_class => sub {
my $self = shift;
my $meta = $self->associated_class;
my $attr_reader = $self->get_read_method;
my %params = (
associated_attribute => $self,
name => $self->name,
($self->has_lifecycle
? (lifecycle => $self->lifecycle)
: ()),
($self->has_dependencies
? (dependencies => $self->dependencies)
: ()),
);
my $service;
if ($self->has_class) {
$service = MooseX::Bread::Board::ConstructorInjection->new(
%params,
class => $self->class,
)
}
elsif ($self->has_block) {
$service = MooseX::Bread::Board::BlockInjection->new(
%params,
block => $self->block,
)
}
elsif ($self->has_literal_value) {
$service = MooseX::Bread::Board::Literal->new(
%params,
value => $self->literal_value,
)
}
else {
return;
}
$meta->add_service($service);
};
around get_value => sub {
my $orig = shift;
my $self = shift;
my ($instance) = @_;
return $self->$orig($instance)
if $self->has_value($instance);
my $val = $instance->get_service($self->name)->get;
$self->verify_against_type_constraint($val, instance => $instance)
if $self->has_type_constraint;
if ($self->should_auto_deref) {
if (ref($val) eq 'ARRAY') {
return wantarray ? @$val : $val;
}
elsif (ref($val) eq 'HASH') {
return wantarray ? %$val : $val;
}
else {
die 'XXX';
}
}
else {
return $val;
}
};
around accessor_metaclass => sub {
my $orig = shift;
my $self = shift;
return Moose::Meta::Class->create_anon_class(
superclasses => [ $self->$orig(@_) ],
roles => [ 'MooseX::Bread::Board::Meta::Role::Accessor' ],
cache => 1
)->name;
};
no Moose::Role;
1;
|