diff options
Diffstat (limited to 'lib/Data/MultiValued/AttributeTrait.pm')
-rw-r--r-- | lib/Data/MultiValued/AttributeTrait.pm | 458 |
1 files changed, 235 insertions, 223 deletions
diff --git a/lib/Data/MultiValued/AttributeTrait.pm b/lib/Data/MultiValued/AttributeTrait.pm index 263b6ee..322feb2 100644 --- a/lib/Data/MultiValued/AttributeTrait.pm +++ b/lib/Data/MultiValued/AttributeTrait.pm @@ -1,4 +1,10 @@ package Data::MultiValued::AttributeTrait; +{ + $Data::MultiValued::AttributeTrait::VERSION = '0.0.1_3'; +} +{ + $Data::MultiValued::AttributeTrait::DIST = 'Data-MultiValued'; +} use Moose::Role; use Data::MultiValued::AttributeAccessors; use MooseX::Types::Moose qw(Str); @@ -7,46 +13,6 @@ use namespace::autoclean; # ABSTRACT: "base role" for traits of multi-valued Moose attributes -=head1 DESCRIPTION - -Don't use this role directly, use -L<Data::MultiValued::AttributeTrait::Tags>, -L<Data::MultiValued::AttributeTrait::Ranges> or -L<Data::MultiValued::AttributeTrait::TagsAndRanges>. - -This role (together with L<Data::MultiValued::AttributeAccessors>) -defines all the basic plumbing to glue C<Data::MultiValued::Tags> etc -into Moose attributes. - -=head1 Implementation details - -The multi-value object is stored in the instance slot named by the -L</full_storage_slot> attribute attribute. C<before> modifiers on -getters load the appropriate value from the multi-value object into -the regular instance slot, C<after> modifiers on setters store the -value from the regular instance slot into the multi-value object. - -=head1 ATTRIBUTES - -These are the attributes that this trait adds to the attribute in -your class. Example: - - has stuff => ( - is => 'rw', - isa => 'Int', - traits => ['MultiValued::Tags'], - predicate => 'has_stuff', - multi_accessor => 'stuff_tagged', - multi_predicate => 'has_stuff_tagged', - ); - -=head2 C<full_storage_slot> - -The instance slot to use to store the C<Data::MultiValued::Tags> or -similar object. Defaults to C<"${name}__MULTIVALUED_STORAGE__">, where -C<$name> is the attribute name. - -=cut has 'full_storage_slot' => ( is => 'ro', @@ -55,30 +21,6 @@ has 'full_storage_slot' => ( ); sub _build_full_storage_slot { shift->name . '__MULTIVALUED_STORAGE__' } -=head2 C<multi_accessor> - -=head2 C<multi_reader> - -=head2 C<multi_writer> - -=head2 C<multi_predicate> - -=head2 C<multi_clearer> - -The names to use for the various additional accessors. See -L<Class::MOP::Attribute> for details. These default to -C<"${name}_multi"> where C<$name> is the name of the corresponding -non-multi accessor. So, for example, - - has stuff => ( - is => 'rw', - traits => ['MultiValued::Tags'], - ); - -will create a C<stuff> read / write accessor and a C<stuff_multi> read -/ write tagged accessor. - -=cut my @accs_to_multiply=qw(accessor reader writer predicate clearer); @@ -90,56 +32,21 @@ for my $acc (@accs_to_multiply) { ); } -=head1 REQUIREMENTS - -These methods must be provided by any class consuming this role. See -L<Data::MultiValued::AttributeTrait::Tags> etc. for examples. - -=head2 C<multivalue_storage_class> - -The class to use to create the multi-value objects. - -=cut requires 'multivalue_storage_class'; -=head2 C<opts_to_pass_set> - -Which options to pass from the multi-value accessors to the C<set> -method of the multi-value object. - -=cut requires 'opts_to_pass_set'; -=head2 C<opts_to_pass_get> - -Which options to pass from the multi-value accessors to the C<get> -method of the multi-value object. - -=cut requires 'opts_to_pass_get'; -=head1 METHODS - -=head2 C<slots> - -Adds the L</full_storage_slot> to the list of used slots. - -=cut around slots => sub { my ($orig, $self) = @_; return ($self->$orig(), $self->full_storage_slot); }; -=head2 C<set_full_storage> - -Stores a new instance of L</multivalue_storage_class> into the -L</full_storage_slot> of the instance. - -=cut sub set_full_storage { my ($self,$instance) = @_; @@ -153,11 +60,6 @@ sub set_full_storage { return $ret; } -=head2 C<get_full_storage> - -Retrieves the value of the L</full_storage_slot> of the instance. - -=cut sub get_full_storage { my ($self,$instance) = @_; @@ -169,13 +71,6 @@ sub get_full_storage { ); } -=head2 C<full_storage> - -Returns an instance of L</multivalue_storage_class>, either by -retrieving it from the instance, or by creating one (and setting it in -the instance). Calls L</get_full_storage> and L</set_full_storage>. - -=cut sub full_storage { my ($self,$instance) = @_; @@ -184,28 +79,9 @@ sub full_storage { || $self->set_full_storage($instance); } -=head2 C<accessor_metaclass> - -Makes sure that all accessors for this attribute are created via the -L<Data::MultiValued::AttributeAccessors> method meta class. - -=cut sub accessor_metaclass { 'Data::MultiValued::AttributeAccessors' } -=head2 C<install_accessors> - -After the regular L<Moose::Meta::Attribute> method, installs the -multi-value accessors. - -Each installed normal accessor gets a multi-value version - -You can add or rename the multi-value version by using the attributes -described above - -If you are passing explicit subrefs for your accessors, things won't work. - -=cut after install_accessors => sub { my ($self) = @_; @@ -246,18 +122,6 @@ sub _filter_opts { return \%ret; } -=head2 C<load_multi_value> - -Retrieves a value from the multi-value object, and stores it in the -regular slot in the instance. If the value is not found, clears the -slot. - -This traps the -L<Data::MultiValued::Exceptions::NotFound|Data::MultiValued::Exceptions/Data::MultiValued::Exceptions::NotFound> -exception that may be thrown by the multi-value object, but re-throws -any other exception. - -=cut sub load_multi_value { my ($self,$instance,$opts) = @_; @@ -283,13 +147,6 @@ sub load_multi_value { } } -=head2 C<raw_clear_value> - -Clears the instance slot. Does the same as -L<Moose::Meta::Attribute/clear_value>, but we need this method because -the other one gets changed by this trait. - -=cut sub raw_clear_value { my ($self,$instance) = @_; @@ -301,12 +158,6 @@ sub raw_clear_value { ); } -=head2 C<store_multi_value> - -Gets the value from the regular slot in the instance, and stores it -into the multi-value object. - -=cut sub store_multi_value { my ($self,$instance,$opts) = @_; @@ -320,12 +171,6 @@ sub store_multi_value { our $dyn_opts = {}; -=head2 C<get_value> - -Before the normal method, calls L</load_multi_value>. Normally, no -options will be passed to the multi-value object C<get> method. - -=cut before get_value => sub { my ($self,$instance) = @_; @@ -333,14 +178,6 @@ before get_value => sub { $self->load_multi_value($instance,$dyn_opts); }; -=head2 C<get_multi_value> - -Sets the options that L</load_multi_value> will use, then calls L</get_value>. - -The options are passed via an ugly C<local>ised package -variable. There might be a better way. - -=cut sub get_multi_value { my ($self,$instance,$opts) = @_; @@ -350,11 +187,6 @@ sub get_multi_value { return $self->get_value($instance); } -=head2 C<set_initial_value> - -After the normal method, calls L</store_multi_value>. - -=cut after set_initial_value => sub { my ($self,$instance,$value) = @_; @@ -362,14 +194,6 @@ after set_initial_value => sub { $self->store_multi_value($instance,$dyn_opts); }; -=head2 C<set_value> - -=head2 C<set_multi_value> - -Just like L</get_value> and L</get_multi_value>, but calling -L</store_multi_value> after the regular C<set_value> - -=cut after set_value => sub { my ($self,$instance,$value) = @_; @@ -385,13 +209,6 @@ sub set_multi_value { return $self->set_value($instance,$value); } -=head2 C<has_value> - -=head2 C<has_multi_value> - -Just like L</get_value> and L</get_multi_value>. - -=cut before has_value => sub { my ($self,$instance) = @_; @@ -407,13 +224,6 @@ sub has_multi_value { return $self->has_value($instance); } -=head2 C<clear_value> - -=head2 C<clear_multi_value> - -Call the C<clear> method on the multi-value object. - -=cut after clear_value => sub { my ($self,$instance) = @_; @@ -430,14 +240,6 @@ sub clear_multi_value { return $self->clear_value($instance); } -=head2 C<get_multi_read_method> - -=head2 C<get_multi_write_method> - -Return the name of the reader or writer method, honoring -L</multi_reader>, L</multi_writer> and L</multi_accessor>. - -=cut sub get_multi_read_method { my $self = shift; @@ -451,18 +253,6 @@ sub get_multi_write_method { || $self->get_write_method . '_multi'; } -=head1 Serialisation helpers - -These are used through -L<Data::MultiValued::UglySerializationHelperRole>. - -=head2 C<_rebless_slot> - -Blesses the value inside the L</full_storage_slot> of the instance -into L</multivalue_storage_class>, then calls C<_rebless_storage> on -it. - -=cut sub _rebless_slot { my ($self,$instance) = @_; @@ -474,13 +264,6 @@ sub _rebless_slot { $st->_rebless_storage; } -=head2 C<_as_hash> - -Returns the result of calling C<_as_hash> on the value inside the -L</full_storage_slot> of the instance. Returns nothing if the slot -does not have a value. - -=cut sub _as_hash { my ($self,$instance) = @_; @@ -492,3 +275,232 @@ sub _as_hash { } 1; + +__END__ +=pod + +=encoding utf-8 + +=head1 NAME + +Data::MultiValued::AttributeTrait - "base role" for traits of multi-valued Moose attributes + +=head1 VERSION + +version 0.0.1_3 + +=head1 DESCRIPTION + +Don't use this role directly, use +L<Data::MultiValued::AttributeTrait::Tags>, +L<Data::MultiValued::AttributeTrait::Ranges> or +L<Data::MultiValued::AttributeTrait::TagsAndRanges>. + +This role (together with L<Data::MultiValued::AttributeAccessors>) +defines all the basic plumbing to glue C<Data::MultiValued::Tags> etc +into Moose attributes. + +=head1 ATTRIBUTES + +=head2 C<full_storage_slot> + +The instance slot to use to store the C<Data::MultiValued::Tags> or +similar object. Defaults to C<"${name}__MULTIVALUED_STORAGE__">, where +C<$name> is the attribute name. + +=head2 C<multi_accessor> + +=head2 C<multi_reader> + +=head2 C<multi_writer> + +=head2 C<multi_predicate> + +=head2 C<multi_clearer> + +The names to use for the various additional accessors. See +L<Class::MOP::Attribute> for details. These default to +C<"${name}_multi"> where C<$name> is the name of the corresponding +non-multi accessor. So, for example, + + has stuff => ( + is => 'rw', + traits => ['MultiValued::Tags'], + ); + +will create a C<stuff> read / write accessor and a C<stuff_multi> read +/ write tagged accessor. + +=head1 METHODS + +=head2 C<slots> + +Adds the L</full_storage_slot> to the list of used slots. + +=head2 C<set_full_storage> + +Stores a new instance of L</multivalue_storage_class> into the +L</full_storage_slot> of the instance. + +=head2 C<get_full_storage> + +Retrieves the value of the L</full_storage_slot> of the instance. + +=head2 C<full_storage> + +Returns an instance of L</multivalue_storage_class>, either by +retrieving it from the instance, or by creating one (and setting it in +the instance). Calls L</get_full_storage> and L</set_full_storage>. + +=head2 C<accessor_metaclass> + +Makes sure that all accessors for this attribute are created via the +L<Data::MultiValued::AttributeAccessors> method meta class. + +=head2 C<install_accessors> + +After the regular L<Moose::Meta::Attribute> method, installs the +multi-value accessors. + +Each installed normal accessor gets a multi-value version + +You can add or rename the multi-value version by using the attributes +described above + +If you are passing explicit subrefs for your accessors, things won't work. + +=head2 C<load_multi_value> + +Retrieves a value from the multi-value object, and stores it in the +regular slot in the instance. If the value is not found, clears the +slot. + +This traps the +L<Data::MultiValued::Exceptions::NotFound|Data::MultiValued::Exceptions/Data::MultiValued::Exceptions::NotFound> +exception that may be thrown by the multi-value object, but re-throws +any other exception. + +=head2 C<raw_clear_value> + +Clears the instance slot. Does the same as +L<Moose::Meta::Attribute/clear_value>, but we need this method because +the other one gets changed by this trait. + +=head2 C<store_multi_value> + +Gets the value from the regular slot in the instance, and stores it +into the multi-value object. + +=head2 C<get_value> + +Before the normal method, calls L</load_multi_value>. Normally, no +options will be passed to the multi-value object C<get> method. + +=head2 C<get_multi_value> + +Sets the options that L</load_multi_value> will use, then calls L</get_value>. + +The options are passed via an ugly C<local>ised package +variable. There might be a better way. + +=head2 C<set_initial_value> + +After the normal method, calls L</store_multi_value>. + +=head2 C<set_value> + +=head2 C<set_multi_value> + +Just like L</get_value> and L</get_multi_value>, but calling +L</store_multi_value> after the regular C<set_value> + +=head2 C<has_value> + +=head2 C<has_multi_value> + +Just like L</get_value> and L</get_multi_value>. + +=head2 C<clear_value> + +=head2 C<clear_multi_value> + +Call the C<clear> method on the multi-value object. + +=head2 C<get_multi_read_method> + +=head2 C<get_multi_write_method> + +Return the name of the reader or writer method, honoring +L</multi_reader>, L</multi_writer> and L</multi_accessor>. + +=head2 C<_rebless_slot> + +Blesses the value inside the L</full_storage_slot> of the instance +into L</multivalue_storage_class>, then calls C<_rebless_storage> on +it. + +=head2 C<_as_hash> + +Returns the result of calling C<_as_hash> on the value inside the +L</full_storage_slot> of the instance. Returns nothing if the slot +does not have a value. + +=head1 ATTRIBUTES + +These are the attributes that this trait adds to the attribute in +your class. Example: + + has stuff => ( + is => 'rw', + isa => 'Int', + traits => ['MultiValued::Tags'], + predicate => 'has_stuff', + multi_accessor => 'stuff_tagged', + multi_predicate => 'has_stuff_tagged', + ); + +=head1 Implementation details + +The multi-value object is stored in the instance slot named by the +L</full_storage_slot> attribute attribute. C<before> modifiers on +getters load the appropriate value from the multi-value object into +the regular instance slot, C<after> modifiers on setters store the +value from the regular instance slot into the multi-value object. + +=head1 REQUIREMENTS + +These methods must be provided by any class consuming this role. See +L<Data::MultiValued::AttributeTrait::Tags> etc. for examples. + +=head2 C<multivalue_storage_class> + +The class to use to create the multi-value objects. + +=head2 C<opts_to_pass_set> + +Which options to pass from the multi-value accessors to the C<set> +method of the multi-value object. + +=head2 C<opts_to_pass_get> + +Which options to pass from the multi-value accessors to the C<get> +method of the multi-value object. + +=head1 Serialisation helpers + +These are used through +L<Data::MultiValued::UglySerializationHelperRole>. + +=head1 AUTHOR + +Gianni Ceccarelli <dakkar@thenautilus.net> + +=head1 COPYRIGHT AND LICENSE + +This software is copyright (c) 2011 by Net-a-Porter.com. + +This is free software; you can redistribute it and/or modify it under +the same terms as the Perl 5 programming language system itself. + +=cut + |