Revision history for Perl extension Moose
0.59
+ * Moose
+ - Add abridged documentation for builder/default/initializer/
+ predicate, and link to more details sections in
+ Class::MOP::Attribute. (t0m)
* Moose::Util::TypeConstraints
- removed prototypes from all but the &-based stuff (mst)
* Moose::Util::TypeConstraints
- Some tests that used Test::Warn if it was available failed
with older versions of Test::Warn. Reported by Fayland. (Dave
Rolsky)
+ - Test firing behavior of triggers in relation to builder/default/
+ lazy_build. (t0m)
* Moose::Meta::Class
- In create(), do not pass "roles" option to the superclass
- added related test that creates an anon metaclass with
accessor respectively, using the same name as the C<$name> of the attribute.
If you need more control over how your accessors are named, you can use the
-I<reader>, I<writer> and I<accessor> options inherited from
+L<reader|Class::MOP::Attribute#reader>, I<|Class::MOP::Attribute#writer> and
+I<|Class::MOP::Attribute#accessor> options inherited from
L<Class::MOP::Attribute>, however if you use those, you won't need the I<is>
option.
the attribute is set. The CODE ref will be passed the instance itself, the
updated value and the attribute meta-object (this is for more advanced fiddling
and can typically be ignored). You B<cannot> have a trigger on a read-only
-attribute.
+attribute.
+
+B<NOTE:> Triggers will only fire when you B<assign> to the attribute,
+either in the constructor, or using the writer. Default and built values will
+B<not> cause the trigger to be fired.
=item I<handles =E<gt> ARRAY | HASH | REGEXP | ROLE | CODE>
Also see L<Moose::Cookbook::Meta::Recipe3> for a metaclass trait
example.
+=item I<builder>
+
+The value of this key is the name of the method that will be called to obtain the value used to
+initialize the attribute. See the documentation in
+L<Class::MOP::Attribute|Class::MOP::Attribute#builder> for more information.
+
+=item I<default>
+
+The value of this key is the default value which will initialize the attribute.
+
+NOTE: If the value is a simple scalar (string or number), then it can be just passed as is.
+However, if you wish to initialize it with a HASH or ARRAY ref, then you need to wrap that inside a CODE reference.
+See the documentation in L<Class::MOP::Attribute|Class::MOP::Attribute#default> for more information.
+
+=item I<initializer>
+
+This may be a method name (referring to a method on the class with this attribute) or a CODE ref.
+The initializer is used to set the attribute value on an instance when the attribute is set during
+instance initialization (but not when the value is being assigned to). See the documentation in
+L<Class::MOP::Attribute|Class::MOP::Attribute#initializer> for more information.
+
+=item I<clearer>
+
+Allows you to clear the value, see the documentation in
+L<Class::MOP::Attribute|Class::MOP::Attribute#clearer> for more information.
+
+=item I<predicate>
+
+Basic test to see if a value has been set in the attribute, see the documentation in
+L<Class::MOP::Attribute|Class::MOP::Attribute#predicate> for more information.
+
=back
=item B<has +$name =E<gt> %options>
use Scalar::Util 'isweak';
-use Test::More tests => 25;
+use Test::More tests => 36;
use Test::Exception;
} '... a trigger must be a CODE ref';
}
+# Triggers do not fire on built values
+
+{
+ package Blarg;
+ use Moose;
+
+ our %trigger_calls;
+ our %trigger_vals;
+ has foo => (is => 'rw', default => sub { 'default foo value' },
+ trigger => sub { my ($self, $val, $attr) = @_;
+ $trigger_calls{foo}++;
+ $trigger_vals{foo} = $val });
+ has bar => (is => 'rw', lazy_build => 1,
+ trigger => sub { my ($self, $val, $attr) = @_;
+ $trigger_calls{bar}++;
+ $trigger_vals{bar} = $val });
+ sub _build_bar { return 'default bar value' }
+ has baz => (is => 'rw', builder => '_build_baz',
+ trigger => sub { my ($self, $val, $attr) = @_;
+ $trigger_calls{baz}++;
+ $trigger_vals{baz} = $val });
+ sub _build_baz { return 'default baz value' }
+}
+
+{
+ my $blarg;
+ lives_ok { $blarg = Blarg->new; } 'Blarg->new() lives';
+ ok($blarg, 'Have a $blarg');
+ foreach my $attr (qw/foo bar baz/) {
+ is($blarg->$attr(), "default $attr value", "$attr has default value");
+ }
+ is_deeply(\%Blarg::trigger_calls, {}, 'No triggers fired');
+ foreach my $attr (qw/foo bar baz/) {
+ $blarg->$attr("Different $attr value");
+ }
+ is_deeply(\%Blarg::trigger_calls, { map { $_ => 1 } qw/foo bar baz/ }, 'All triggers fired once on assign');
+ is_deeply(\%Blarg::trigger_vals, { map { $_ => "Different $_ value" } qw/foo bar baz/ }, 'All triggers given assigned values');
+
+ lives_ok { $blarg => Blarg->new( map { $_ => "Yet another $_ value" } qw/foo bar baz/ ) } '->new() with parameters';
+ is_deeply(\%Blarg::trigger_calls, { map { $_ => 2 } qw/foo bar baz/ }, 'All triggers fired once on construct');
+ is_deeply(\%Blarg::trigger_vals, { map { $_ => "Yet another $_ value" } qw/foo bar baz/ }, 'All triggers given assigned values');
+}