simplify value widgets to reduce PROCESS calls, make some classes immutable which...
[catagits/Reaction.git] / lib / Reaction / Meta / Attribute.pm
CommitLineData
7adfd53f 1package Reaction::Meta::Attribute;
2
3use Moose;
4
5extends 'Moose::Meta::Attribute';
6
7#is => 'Bool' ? or leave it open
8has lazy_fail =>
9 (is => 'ro', reader => 'is_lazy_fail', required => 1, default => 0);
10has lazy_build =>
11 (is => 'ro', reader => 'is_lazy_build', required => 1, default => 0);
12
13around _process_options => sub {
14 my $super = shift;
15 my ($class, $name, $options) = @_;
16
17 my $fail = $options->{lazy_fail}; #will this autovivify?
18 my $build = $options->{lazy_build};
19
20 if ( $fail || $build) {
21 confess("You may not use both lazy_build and lazy_fail for one attribute")
22 if $fail && $build;
23 confess("You may not supply a default value when using lazy_build or lazy_fail")
24 if exists $options->{default};
25
26 $options->{lazy} = 1;
27 $options->{required} = 1;
28
29 my $builder = ($name =~ /^_/) ? "_build${name}" : "build_${name}";
30 $options->{default} = $fail ?
31 sub { confess "${name} must be provided before calling reader" } :
32 sub{ shift->$builder };
e22de101 33
34 $options->{clearer} ||= ($name =~ /^_/) ? "_clear${name}" : "clear_${name}"
35 if $build;
7adfd53f 36 }
37
38 #we are using this everywhere so might as well move it here.
39 $options->{predicate} ||= ($name =~ /^_/) ? "_has${name}" : "has_${name}"
40 if !$options->{required} || $options->{lazy};
41
42
43 $super->($class, $name, $options);
44};
45
a5200252 46__PACKAGE__->meta->make_immutable(inline_constructor => 0);
47
7adfd53f 481;
49
50__END__;
51
52=head1 NAME
53
54Reaction::Meta::Attribute
55
56=head1 SYNOPSIS
57
58 has description => (is => 'rw', isa => 'Str', lazy_fail => 1);
59
60 # OR
61 has description => (is => 'rw', isa => 'Str', lazy_build => 1);
62 sub build_description{ "My Description" }
63
64 # OR
65 has _description => (is => 'rw', isa => 'Str', lazy_build => 1);
66 sub _build_description{ "My Description" }
67
68=head1 Method-naming conventions
69
70Reaction::Meta::Attribute will never override the values you set for method names,
71but if you do not it will follow these basic rules:
72
73Attributes with a name that starts with an underscore will default to using
74builder and predicate method names in the form of the attribute name preceeded by
75either "_has" or "_build". Otherwise the method names will be in the form of the
76attribute names preceeded by "has_" or "build_". e.g.
77
78 #auto generates "_has_description" and expects "_build_description"
79 has _description => (is => 'rw', isa => 'Str', lazy_build => 1);
80
81 #auto generates "has_description" and expects "build_description"
82 has description => (is => 'rw', isa => 'Str', lazy_build => 1);
83
84=head2 Predicate generation
85
86All non-required or lazy attributes will have a predicate automatically
87generated for them if one is not already specified.
88
89=head2 lazy_fail
90
91=head2 lazy_build
92
93lazy_build will lazily build to the return value of a user-supplied builder sub
94 The builder sub will recieve C<$self> as the first argument.
95
96lazy_fail will simply fail if it is called without first having set the value.
97
98=head1 AUTHORS
99
100See L<Reaction::Class> for authors.
101
102=head1 LICENSE
103
104See L<Reaction::Class> for the license.
105
106=cut