From: Tomas Doran Date: Mon, 6 Oct 2008 16:14:51 +0000 (+0000) Subject: Docs for things in Class::MOP::Attribute + tests for trigger behaviours X-Git-Tag: 0.59~21 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=010997ca7f90b5313e23aa7bbdd6535c7ab265cc;p=gitmo%2FMoose.git Docs for things in Class::MOP::Attribute + tests for trigger behaviours --- diff --git a/Changes b/Changes index 8412e68..c783632 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,10 @@ 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 @@ -11,6 +15,8 @@ Revision history for Perl extension Moose - 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 diff --git a/lib/Moose.pm b/lib/Moose.pm index 2ddb8bd..4e95778 100644 --- a/lib/Moose.pm +++ b/lib/Moose.pm @@ -418,7 +418,8 @@ only). These will create either a read/write accessor or a read-only 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, I and I options inherited from +L, I<|Class::MOP::Attribute#writer> and +I<|Class::MOP::Attribute#accessor> options inherited from L, however if you use those, you won't need the I option. @@ -471,7 +472,11 @@ The I option is a CODE reference which will be called after the value o 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 have a trigger on a read-only -attribute. +attribute. + +B Triggers will only fire when you B to the attribute, +either in the constructor, or using the writer. Default and built values will +B cause the trigger to be fired. =item I ARRAY | HASH | REGEXP | ROLE | CODE> @@ -606,6 +611,37 @@ resolved to a class name. Also see L for a metaclass trait example. +=item I + +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 for more information. + +=item I + +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 for more information. + +=item I + +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 for more information. + +=item I + +Allows you to clear the value, see the documentation in +L for more information. + +=item I + +Basic test to see if a value has been set in the attribute, see the documentation in +L for more information. + =back =item B %options> diff --git a/t/020_attributes/004_attribute_triggers.t b/t/020_attributes/004_attribute_triggers.t index 0695dc3..637d604 100644 --- a/t/020_attributes/004_attribute_triggers.t +++ b/t/020_attributes/004_attribute_triggers.t @@ -5,7 +5,7 @@ use warnings; use Scalar::Util 'isweak'; -use Test::More tests => 25; +use Test::More tests => 36; use Test::Exception; @@ -115,4 +115,46 @@ 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'); +}