#is => 'Bool' ? or leave it open
has lazy_fail =>
(is => 'ro', reader => 'is_lazy_fail', required => 1, default => 0);
-has lazy_build =>
- (is => 'ro', reader => 'is_lazy_build', required => 1, default => 0);
+
+around legal_options_for_inheritance => sub {
+ return (shift->(@_), qw/valid_values/);
+};
around _process_options => sub {
my $super = shift;
my ($class, $name, $options) = @_;
- my $fail = $options->{lazy_fail}; #will this autovivify?
- my $build = $options->{lazy_build};
+ my $fail = $options->{lazy_fail};
- if ( $fail || $build) {
+ if ( $fail ) {
confess("You may not use both lazy_build and lazy_fail for one attribute")
- if $fail && $build;
- confess("You may not supply a default value when using lazy_build or lazy_fail")
- if exists $options->{default};
+ if $fail && $options->{lazy_build};
$options->{lazy} = 1;
$options->{required} = 1;
-
- my $builder = ($name =~ /^_/) ? "_build${name}" : "build_${name}";
- $options->{default} = $fail ?
- sub { confess "${name} must be provided before calling reader" } :
- sub{ shift->$builder };
+ $options->{default} = sub { confess "${name} must be provided before calling reader" };
}
#we are using this everywhere so might as well move it here.
$options->{predicate} ||= ($name =~ /^_/) ? "_has${name}" : "has_${name}"
if !$options->{required} || $options->{lazy};
-
$super->($class, $name, $options);
};
+foreach my $type (qw(clearer predicate)) {
+
+ my $value_meth = do {
+ if ($type eq 'clearer') {
+ 'clear_value'
+ } elsif ($type eq 'predicate') {
+ 'has_value'
+ } else {
+ confess "NOTREACHED";
+ }
+ };
+
+ __PACKAGE__->meta->add_method("get_${type}_method" => sub {
+ my $self = shift;
+ my $info = $self->$type;
+ return $info unless ref $info;
+ my ($name) = %$info;
+ return $name;
+ });
+
+ __PACKAGE__->meta->add_method("get_${type}_method_ref" => sub {
+ my $self = shift;
+ if ((my $name = $self->${\"get_${type}_method"}) && $self->associated_class) {
+ return $self->associated_class->get_method($name);
+ } else {
+ return sub { $self->$value_meth(@_); }
+ }
+ });
+}
+
+__PACKAGE__->meta->make_immutable(inline_constructor => 0);
+
1;
__END__;
has description => (is => 'rw', isa => 'Str', lazy_fail => 1);
- # OR
- has description => (is => 'rw', isa => 'Str', lazy_build => 1);
- sub build_description{ "My Description" }
-
- # OR
- has _description => (is => 'rw', isa => 'Str', lazy_build => 1);
- sub _build_description{ "My Description" }
-
=head1 Method-naming conventions
Reaction::Meta::Attribute will never override the values you set for method names,
attribute names preceeded by "has_" or "build_". e.g.
#auto generates "_has_description" and expects "_build_description"
- has _description => (is => 'rw', isa => 'Str', lazy_build => 1);
+ has _description => (is => 'rw', isa => 'Str', lazy_fail => 1);
#auto generates "has_description" and expects "build_description"
- has description => (is => 'rw', isa => 'Str', lazy_build => 1);
+ has description => (is => 'rw', isa => 'Str', lazy_fail => 1);
=head2 Predicate generation
=head2 lazy_fail
-=head2 lazy_build
-
-lazy_build will lazily build to the return value of a user-supplied builder sub
- The builder sub will recieve C<$self> as the first argument.
-
-lazy_fail will simply fail if it is called without first having set the value.
+lazy_fail will fail if it is called without first having set the value.
=head1 AUTHORS