summaryrefslogtreecommitdiff
path: root/lib/Class/MakeMethods/Template/Generic.pm
diff options
context:
space:
mode:
authorAndreas Brachold <vdr07@deltab.de>2007-11-10 17:53:53 +0000
committerAndreas Brachold <vdr07@deltab.de>2007-11-10 17:53:53 +0000
commitcfdd733c17cfa4f1a43b827a656e9e53cc2524ac (patch)
treeb6f659b1281f77628b36768f0888f67b65f9ca48 /lib/Class/MakeMethods/Template/Generic.pm
parent9c6c30350161efd74faa3c3705096aecb71c0e81 (diff)
downloadxxv-cfdd733c17cfa4f1a43b827a656e9e53cc2524ac.tar.gz
xxv-cfdd733c17cfa4f1a43b827a656e9e53cc2524ac.tar.bz2
* Remove unsed packages
* Reorder exit routines
Diffstat (limited to 'lib/Class/MakeMethods/Template/Generic.pm')
-rw-r--r--lib/Class/MakeMethods/Template/Generic.pm2349
1 files changed, 0 insertions, 2349 deletions
diff --git a/lib/Class/MakeMethods/Template/Generic.pm b/lib/Class/MakeMethods/Template/Generic.pm
deleted file mode 100644
index 368f21f..0000000
--- a/lib/Class/MakeMethods/Template/Generic.pm
+++ /dev/null
@@ -1,2349 +0,0 @@
-=head1 NAME
-
-Class::MakeMethods::Template::Generic - Templates for common meta-method types
-
-=head1 SYNOPSIS
-
- package MyObject;
- use Class::MakeMethods (
- 'Template::Hash:new' => [ 'new' ],
- 'Template::Hash:scalar' => [ 'foo' ]
- 'Template::Static:scalar' => [ 'bar' ]
- );
-
- package main;
-
- my $obj = MyObject->new( foo => "Foozle", bar => "Bozzle" );
- print $obj->foo();
- $obj->bar("Bamboozle");
-
-=head1 DESCRIPTION
-
-This package provides a variety of abstract interfaces for constructors
-and accessor methods, which form a common foundation for meta-methods
-provided by the Hash, Scalar, Flyweight, Static, PackageVar, and
-ClassVar implementations.
-
-Generally speaking, the Generic meta-methods define calling interfaces
-and behaviors which are bound to differently scoped data by each
-of those subclasses.
-
-=cut
-
-########################################################################
-
-package Class::MakeMethods::Template::Generic;
-
-use Class::MakeMethods::Template '-isasubclass';
-
-$VERSION = 1.008;
-use strict;
-use Carp;
-
-# use AutoLoader 'AUTOLOAD';
-
-########################################################################
-
-sub generic {
- {
- 'params' => {
- },
- 'modifier' => {
- '-import' => { 'Template::Universal:generic' => '*' },
- },
- 'code_expr' => {
- '-import' => { 'Template::Universal:generic' => '*' },
- '_VALUE_' => undef,
- '_REF_VALUE_' => q{ _VALUE_ },
- '_GET_VALUE_' => q{ _VALUE_ },
- '_SET_VALUE_{}' => q{ ( _VALUE_ = * ) },
- '_PROTECTED_SET_VALUE_{}' => q{ (_ACCESS_PROTECTED_ and _SET_VALUE_{*}) },
- '_PRIVATE_SET_VALUE_{}' => q{ ( _ACCESS_PRIVATE_ and _SET_VALUE_{*} ) },
- },
- }
-}
-
-# 1;
-
-# __END__
-
-########################################################################
-
-=head2 new Constructor
-
-There are several types of hash-based object constructors to choose from.
-
-Each of these methods creates and returns a reference to a new
-blessed instance. They differ in how their (optional) arguments
-are interpreted to set initial values, and in how they operate when
-called as class or instance methods.
-
-B<Interfaces>: The following interfaces are supported.
-
-=over 4
-
-=item -with_values,
-
-Provides the with_values behavior.
-
-=item -with_init
-
-Provides the with_init behavior.
-
-=item -with_methods
-
-Provides the with_methods behavior.
-
-=item -new_and_init
-
-Provides the with_init behavior for I<*>, and the general purpose method_init behavior as an init method.
-
-=item -copy_with_values
-
-Provides the copy behavior.
-
-=back
-
-B<Behaviors>: The following types of constructor methods are available.
-
-=over 4
-
-=item with_values
-
-Creates and blesses a new instance.
-
-If arguments are passed they are included in the instance, otherwise it will be empty.
-
-Returns the new instance.
-
-May be called as a class or instance method.
-
-=item with_methods
-
-Creates, blesses, and returns a new instance.
-
-The arguments are treated as a hash of method-name/argument-value
-pairs, with each such pair causing a call C<$self-E<gt>name($value)>.
-
-=item with_init
-
-Creates and blesses a new instance, then calls a method named C<init>,
-passing along any arguments that were initially given.
-
-Returns the new instance.
-
-The I<init>() method should be defined in the class declaring these methods.
-
-May be called as a class or instance method.
-
-=item and_then_init
-
-Creates a new instance using method-name/argument-value pairs, like C<with_methods>, but then calls a method named C<init> before returning the new object. The C<init> method does not receive any arguments.
-
-The I<init>() method should be defined in the class declaring these methods.
-
-=item instance_with_methods
-
-If called as a class method, creates, blesses, and returns a new
-instance. If called as an object method, operates on and returns
-the existing instance.
-
-Accepts name-value pair arguments, or a reference to hash of such
-pairs, and calls the named method for each with the supplied value
-as a single argument. (See the Universal method_init behavior for
-more discussion of this pattern.)
-
-=item copy_with values
-
-Produce a copy of an instance. Can not be called as a class method.
-
-The copy is a *shallow* copy; any references will be shared by the
-instance upon which the method is called and the returned newborn.
-
-If a list of key-value pairs is passed as arguments to the method,
-they are added to the copy, overwriting any values with the same
-key that may have been copied from the original.
-
-=item copy_with_methods
-
-Produce a copy of an instance. Can not be called as a class method.
-
-The copy is a *shallow* copy; any references will be shared by the
-instance upon which the method is called and the returned newborn.
-
-Accepts name-value pair arguments, or a reference to hash of such
-pairs, and calls the named method on the copy for each with the
-supplied value as a single argument before the copy is returned.
-
-=item copy_instance_with_values
-
-If called as a class method, creates, blesses, and returns a new
-instance. If called as an object method, produces and returns a
-copy of an instance.
-
-The copy is a *shallow* copy; any references will be shared by the
-instance upon which the method is called and the returned newborn.
-
-If a list of key-value pairs is passed as arguments to the method,
-they are added to the copy, overwriting any values with the same
-key that may have been copied from the original.
-
-=item copy_instance_with_methods
-
-If called as a class method, creates, blesses, and returns a new
-instance. If called as an object method, produces and returns a
-copy of an instance.
-
-The copy is a *shallow* copy; any references will be shared by the
-instance upon which the method is called and the returned newborn.
-
-Accepts name-value pair arguments, or a reference to hash of such
-pairs, and calls the named method on the copy for each with the supplied value as
-a single argument before the copy is returned.
-
-=back
-
-B<Parameters>: The following parameters are supported:
-
-=over 4
-
-=item init_method
-
-The name of the method to call after creating a new instance. Defaults to 'init'.
-
-=back
-
-=cut
-
-sub new {
- {
- '-import' => {
- # 'Template::Generic:generic' => '*',
- },
- 'interface' => {
- default => 'with_methods',
- with_values => 'with_values',
- with_methods => 'with_methods',
- with_init => 'with_init',
- and_then_init => 'and_then_init',
- new_and_init => { '*'=>'new_with_init', 'init'=>'method_init'},
- instance_with_methods => 'instance_with_methods',
- copy => 'copy_with_values',
- copy_with_values => 'copy_with_values',
- copy_with_methods => 'copy_with_methods',
- copy_instance_with_values => 'copy_instance_with_values',
- copy_instance_with_methods => 'copy_instance_with_methods',
- },
- 'behavior' => {
- 'with_methods' => q{
- $self = _EMPTY_NEW_INSTANCE_;
- _CALL_METHODS_FROM_HASH_
- return $self;
- },
- 'with_values' => q{
- $self = _EMPTY_NEW_INSTANCE_;
- _SET_VALUES_FROM_HASH_
- return $self;
- },
- 'with_init' => q{
- $self = _EMPTY_NEW_INSTANCE_;
- my $init_method = $m_info->{'init_method'} || 'init';
- $self->$init_method( @_ );
- return $self;
- },
- 'and_then_init' => q{
- $self = _EMPTY_NEW_INSTANCE_;
- _CALL_METHODS_FROM_HASH_
- my $init_method = $m_info->{'init_method'} || 'init';
- $self->$init_method();
- return $self;
- },
- 'instance_with_methods' => q{
- $self = ref ($self) ? $self : _EMPTY_NEW_INSTANCE_;
- _CALL_METHODS_FROM_HASH_
- return $self;
- },
- 'copy_with_values' => q{
- @_ = ( %$self, @_ );
- $self = _EMPTY_NEW_INSTANCE_;
- _SET_VALUES_FROM_HASH_
- return $self;
- },
- 'copy_with_methods' => q{
- @_ = ( %$self, @_ );
- $self = _EMPTY_NEW_INSTANCE_;
- _CALL_METHODS_FROM_HASH_
- return $self;
- },
- 'copy_instance_with_values' => q{
- $self = bless { ( ref $self ? %$self : () ) }, _SELF_CLASS_;
- _SET_VALUES_FROM_HASH_
- return $self;
- },
- 'copy_instance_with_methods' => q{
- $self = bless { ref $self ? %$self : () }, _SELF_CLASS_;
- _CALL_METHODS_FROM_HASH_
- return $self;
- },
- },
- }
-}
-
-########################################################################
-
-=head2 scalar Accessor
-
-A generic scalar-value accessor meta-method which serves as an
-abstraction for basic "get_set" methods and numerous related
-interfaces
-
- use Class::MakeMethods -MakerClass => "...",
- scalar => [ 'foo', 'bar' ];
- ...
- $self->foo( 'my new foo value' );
- print $self->foo();
-
-(Note that while you can use the scalar methods to store references to
-various data structures, there are other meta-methods defined below that
-may be more useful for managing references to arrays, hashes, and objects.)
-
-B<Interfaces>: The following calling interfaces are available.
-
-=over 4
-
-=item get_set (default)
-
-Provides get_set method for I<*>.
-
-Example: Create method foo, which sets the value of 'foo' for this
-instance if an argument is passed in, and then returns the value
-whether or not it's been changed:
-
- use Class::MakeMethods -MakerClass => "...",
- scalar => [ 'foo' ];
-
-=item get_protected_set
-
-Provides an get_set accessor for I<*> that croaks if a new value
-is passed in from a package that is not a subclass of the declaring
-one.
-
-=item get_private_set
-
-Provides an get_set accessor for I<*> that croaks if a new value
-is passed in from a package other than the declaring one.
-
-=item read_only
-
-Provides an accessor for I<*> that does not modify its value. (Its
-initial value would have to be set by some other means.)
-
-=item eiffel
-
-Provides get behavior as I<*>, and set behavior as set_I<*>.
-
-Example: Create methods bar which returns the value of 'bar' for
-this instance (takes no arguments), and set_bar, which sets the
-value of 'bar' (no return):
-
- use Class::MakeMethods -MakerClass => "...",
- scalar => [ --eiffel => 'bar' ];
-
-=item java
-
-Provides get behavior as getI<*>, and set behavior as setI<*>.
-
-Example: Create methods getBaz which returns the value of 'Baz'
-for this instance (takes no arguments), and setBaz, which sets the
-value for this instance (no return):
-
- use Class::MakeMethods -MakerClass => "...",
- scalar => [ --java => 'Baz' ];
-
-
-=item init_and_get
-
-Creates methods which cache their results in a hash key.
-
-Provides the get_init behavior for I<*>, and an delete behavior for clear_I<*>.
-Specifies default value for init_method parameter of init_I<*>.
-
-
-=item with_clear
-
-Provides get_set behavior for I<*>, and a clear_I<*> method.
-
-=back
-
-
-B<Behaviors>: The following types of accessor methods are available.
-
-=over 4
-
-=item get_set
-
-If no argument is provided, returns the value of the current instance. The value defaults to undef.
-
-If an argument is provided, it is stored as the value of the current
-instance (even if the argument is undef), and that value is returned.
-
-Also available as get_protected_set and get_private_set, which are
-available for public read-only access, but have access control
-limitations.
-
-=item get
-
-Returns the value from the current instance.
-
-=item set
-
-Sets the value for the current instance. If called with no arguments,
-the value is set to undef. Does not return a value.
-
-=item clear
-
-Sets value to undef.
-
-=item get_set_chain
-
-Like get_set, but if called with an argument, returns the object it was called on. This allows a series of mutators to be called as follows:
-
- package MyObject;
- use Class::MakeMethods (
- 'Template::Hash:scalar --get_set_chain' => 'foo bar baz'
- );
- ...
-
- my $obj = MyObject->new->foo('Foozle');
- $obj->bar("none")->baz("Brazil");
- print $obj->foo, $obj->bar, $obj->baz;
-
-=item get_set_prev
-
-Like get_set, but if called with an argument, returns the previous value before it was changed to the new one.
-
-=item get_init
-
-If the value is currently undefined, calls the init_method. Returns the value.
-
-=back
-
-B<Parameters>: The following parameters are supported:
-
-=over 4
-
-=item init_method
-
-The name of a method to be called to initialize this meta-method.
-
-Only used by the get_init behavior.
-
-=back
-
-=cut
-
-sub scalar {
- {
- '-import' => { 'Template::Generic:generic' => '*' },
- 'interface' => {
- default => 'get_set',
- get_set => { '*'=>'get_set' },
- noclear => { '*'=>'get_set' },
- with_clear => { '*'=>'get_set', 'clear_*'=>'clear' },
-
- read_only => { '*'=>'get' },
- get_private_set => 'get_private_set',
- get_protected_set => 'get_protected_set',
-
- eiffel => { '*'=>'get', 'set_*'=>'set_return' },
- java => { 'get*'=>'get', 'set*'=>'set_return' },
-
- init_and_get => { '*'=>'get_init', -params=>{ init_method=>'init_*' } },
-
- },
- 'behavior' => {
- 'get' => q{ _GET_VALUE_ },
- 'set' => q{ _SET_VALUE_{ shift() } },
- 'set_return' => q{ _BEHAVIOR_{set}; return },
- 'clear' => q{ _SET_VALUE_{ undef } },
- 'defined' => q{ defined _VALUE_ },
-
- 'get_set' => q {
- if ( scalar @_ ) {
- _BEHAVIOR_{set}
- } else {
- _BEHAVIOR_{get}
- }
- },
- 'get_set_chain' => q {
- if ( scalar @_ ) {
- _BEHAVIOR_{set};
- return _SELF_
- } else {
- _BEHAVIOR_{get}
- }
- },
- 'get_set_prev' => q {
- my $value = _BEHAVIOR_{get};
- if ( scalar @_ ) {
- _BEHAVIOR_{set};
- }
- return $value;
- },
-
- 'get_private_set' => q{
- if ( scalar @_ ) {
- _PRIVATE_SET_VALUE_{ shift() }
- } else {
- _BEHAVIOR_{get}
- }
- },
- 'get_protected_set' => q{
- if ( scalar @_ ) {
- _PROTECTED_SET_VALUE_{ shift() }
- } else {
- _BEHAVIOR_{get}
- }
- },
- 'get_init' => q{
- if ( ! defined _VALUE_ ) {
- my $init_method = _ATTR_REQUIRED_{'init_method'};
- _SET_VALUE_{ _SELF_->$init_method( @_ ) };
- } else {
- _BEHAVIOR_{get}
- }
- },
-
- },
- 'params' => {
- new_method => 'new'
- },
- }
-}
-
-########################################################################
-
-=head2 string Accessor
-
-A generic scalar-value accessor meta-method which serves as an
-abstraction for basic "get_set" methods and numerous related
-interfaces
-
- use Class::MakeMethods -MakerClass => "...",
- string => [ 'foo', 'bar' ];
- ...
- $self->foo( 'my new foo value' );
- print $self->foo();
-
-This meta-method extends the scalar meta-method, and supports the same interfaces and parameters.
-
-However, it generally treats values as strings, and can not be used to store references.
-
-B<Interfaces>: In addition to those provided by C<scalar>, the following calling interfaces are available.
-
-=over 4
-
-=item -get_concat
-
-Provides the get_concat behavior for I<*>, and a clear_I<*> method.
-
-Example:
-
- use Class::MakeMethods
- get_concat => { name => 'words', join => ", " };
-
- $obj->words('foo');
- $obj->words('bar');
- $obj->words() eq 'foo, bar';
-
-=back
-
-B<Behaviors>: In addition to those provided by C<scalar>, the following types of accessor methods are available.
-
-=over 4
-
-=item concat
-
-Concatenates the argument value with the existing value.
-
-=item get_concat
-
-Like get_set except sets do not clear out the original value, but instead
-concatenate the new value to the existing one.
-
-=back
-
-B<Parameters>: In addition to those provided by C<scalar>, the following parameters are supported.
-
-=over 4
-
-=item join
-
-If the join parameter is defined, each time the get_concat behavior
-is invoked, it will glue its argument onto any existing value with
-the join string as the separator. The join field is applied I<between>
-values, not prior to the first or after the last. Defaults to undefined
-
-=back
-
-=cut
-
-sub string {
- {
- '-import' => { 'Template::Generic:scalar' => '*' },
- 'interface' => {
- get_concat => { '*'=>'get_concat', 'clear_*'=>'clear',
- -params=>{ 'join' => '' }, },
- },
- 'params' => {
- 'return_value_undefined' => '',
- },
- 'behavior' => {
- 'get' => q{
- if ( defined( my $value = _GET_VALUE_) ) {
- _GET_VALUE_;
- } else {
- _STATIC_ATTR_{return_value_undefined};
- }
- },
- 'set' => q{
- my $new_value = shift();
- _SET_VALUE_{ "$new_value" };
- },
- 'concat' => q{
- my $new_value = shift();
- if ( defined( my $value = _GET_VALUE_) ) {
- _SET_VALUE_{join( _STATIC_ATTR_{join}, $value, $new_value)};
- } else {
- _SET_VALUE_{ "$new_value" };
- }
- },
- 'get_concat' => q{
- if ( scalar @_ ) {
- _BEHAVIOR_{concat}
- } else {
- _BEHAVIOR_{get}
- }
- },
- },
- }
-}
-
-########################################################################
-
-=head2 string_index
-
- string_index => [ qw / foo bar baz / ]
-
-Creates string accessor methods, like string above, but also
-maintains a static hash index in which each object is stored under
-the value of the field when the slot is set.
-
-This is a unique index, so only one object can have a given key.
-If an object has a slot set to a value which another object is
-already set to the object currently set to that value has that slot
-set to undef and the new object will be put into the hash under
-that value.
-
-Objects with undefined values are not stored in the index.
-
-Note that to free items from memory, you must clear these values!
-
-B<Methods>:
-
-=over 4
-
-=item *
-
-The method find_x is defined which if called with any arguments
-returns a list of the objects stored under those values in the
-hash. Called with no arguments, it returns a reference to the hash.
-
-=back
-
-B<Profiles>:
-
-=over 4
-
-=item *
-
-find_or_new
-
- 'string_index -find_or_new' => [ qw / foo bar baz / ]
-
-Just like string_index except the find_x method is defined to call the new
-method to create an object if there is no object already stored under
-any of the keys you give as arguments.
-
-=back
-
-=cut
-
-sub string_index {
- ( {
- '-import' => { 'Template::Generic:generic' => '*' },
- 'params' => {
- 'new_method' => 'new',
- },
- 'interface' => {
- default => { '*'=>'get_set', 'clear_*'=>'clear', 'find_*'=>'find' },
- find_or_new=>{'*'=>'get_set', 'clear_*'=>'clear', 'find_*'=>'find_or_new'}
- },
- 'code_expr' => {
- _REMOVE_FROM_INDEX_ => q{
- if (defined ( my $old_v = _GET_VALUE_ ) ) {
- delete _ATTR_{'index'}{ $old_v };
- }
- },
- _ADD_TO_INDEX_ => q{
- if (defined ( my $new_value = _GET_VALUE_ ) ) {
- if ( my $old_item = _ATTR_{'index'}{$new_value} ) {
- # There's already an object stored under that value so we
- # need to unset it's value.
- # And maybe issue a warning? Or croak?
- my $m_name = _ATTR_{'name'};
- $old_item->$m_name( undef );
- }
-
- # Put ourself in the index under that value
- _ATTR_{'index'}{$new_value} = _SELF_;
- }
- },
- _INDEX_HASH_ => '_ATTR_{index}',
- },
- 'behavior' => {
- '-init' => [ sub {
- my $m_info = $_[0];
- defined $m_info->{'index'} or $m_info->{'index'} = {};
- return;
- } ],
- 'get' => q{
- return _GET_VALUE_;
- },
- 'set' => q{
- my $new_value = shift;
-
- _REMOVE_FROM_INDEX_
-
- # Set our value to new
- _SET_VALUE_{ $new_value };
-
- _ADD_TO_INDEX_
- },
- 'get_set' => q{
- if ( scalar @_ ) {
- _BEHAVIOR_{set}
- } else {
- _BEHAVIOR_{get}
- }
- },
- 'clear' => q{
- _REMOVE_FROM_INDEX_
- _SET_VALUE_{ undef };
- },
- 'find' => q{
- if ( scalar @_ ) {
- return @{ _ATTR_{'index'} }{ @_ };
- } else {
- return _INDEX_HASH_
- }
- },
- 'find_or_new' => q{
- if ( scalar @_ ) {
- my $class = _SELF_CLASS_;
- my $new_method = _ATTR_REQUIRED_{'new_method'};
- my $m_name = _ATTR_{'name'};
- foreach (@_) {
- next if defined _ATTR_{'index'}{$_};
- # create new instance and set its value; it'll add itself to index
- $class->$new_method()->$m_name($_);
- }
- return @{ _ATTR_{'index'} }{ @_ };
- } else {
- return _INDEX_HASH_
- }
- },
- },
- } )
-}
-
-########################################################################
-
-=head2 number Accessor
-
-A generic scalar-value accessor meta-method which serves as an
-abstraction for basic "get_set" methods and numerous related
-interfaces
-
- use Class::MakeMethods -MakerClass => "...",
- string => [ 'foo', 'bar' ];
- ...
- $self->foo( 23 );
- print $self->foo();
-
-This meta-method extends the scalar meta-method, and supports the same interfaces and parameters.
-
-However, it generally treats values as numbers, and can not be used to store strings or references.
-
-B<Interfaces>: In addition to those provided by C<scalar>, the following calling interfaces are available.
-
-=over 4
-
-=item -counter
-
-Provides the numeric get_set behavior for I<*>, and numeric I<*>_incr and I<*>_reset methods.
-
-=back
-
-B<Behaviors>: In addition to those provided by C<scalar>, the following types of accessor methods are available.
-
-=over 4
-
-=item get_set
-
-The get_set behavior is similar to the default scalar behavior except that empty values are treated as zero.
-
-=item increment
-
-If no argument is provided, increments the I<hash_key> value by 1.
-If an argument is provided, the value is incremented by that amount.
-Returns the increased value.
-
-=item clear
-
-Sets the value to zero.
-
-=back
-
-=cut
-
-sub number {
- {
- '-import' => { 'Template::Generic:scalar' => '*' },
- 'interface' => {
- counter => { '*'=>'get_set', '*_incr'=>'incr', '*_reset'=>'clear' },
- },
- 'params' => {
- 'return_value_undefined' => 0,
- },
- 'behavior' => {
- 'get_set' => q{
- if ( scalar @_ ) {
- local $_ = shift;
- if ( defined $_ ) {
- croak "Can't set _STATIC_ATTR_{name} to non-numeric value '$_'"
- if ( /[^\+\-\,\d\.e]/ );
- s/\,//g;
- }
- _SET_VALUE_{ $_ }
- }
- defined( _GET_VALUE_ ) ? _GET_VALUE_
- : _STATIC_ATTR_{return_value_undefined}
- },
- 'incr' => q{
- _VALUE_ ||= 0;
- _VALUE_ += ( scalar @_ ? shift : 1 )
- },
- 'decr' => q{
- _VALUE_ ||= 0;
- _VALUE_ -= ( scalar @_ ? shift : 1 )
- },
- },
- }
-}
-
-########################################################################
-
-=head2 boolean Accessor
-
-A generic scalar-value accessor meta-method which serves as an abstraction for basic "get_set" methods and numerous related interfaces
-
- use Class::MakeMethods -MakerClass => "...",
- string => [ 'foo', 'bar' ];
- ...
- $self->foo( 1 );
- print $self->foo();
- $self->clear_foo;
-
-This meta-method extends the scalar meta-method, and supports the
-same interfaces and parameters. However, it generally treats values
-as true-or-false flags, and can not be used to store strings,
-numbers, or references.
-
-B<Interfaces>:
-
-=over 4
-
-=item flag_set_clear (default)
-
-Provides the get_set behavior for I<*>, and set_I<*> and clear_I<*> methods to set the value to true or false.
-
-=back
-
-B<Behaviors>: In addition to those provided by C<scalar>, the following types of accessor methods are available.
-
-=over 4
-
-=item get_set
-
-The get_set behavior is similar to the get_set scalar behavior
-except that empty or false values are treated as zero, and true
-values are treated as zero.
-
-=item set_true
-
-Sets the value to one.
-
-=item set_false
-
-Sets the value to zero.
-=back
-
-=cut
-
-sub boolean {
- {
- '-import' => { 'Template::Generic:scalar' => '*' },
- 'interface' => {
- default => {'*'=>'get_set', 'clear_*'=>'set_false',
- 'set_*'=>'set_true'},
- flag_set_clear => {'*'=>'get_set', 'clear_*'=>'set_false',
- 'set_*'=>'set_true'},
- },
- 'behavior' => {
- 'get' => q{ _GET_VALUE_ || 0 },
- 'set' => q{
- if ( shift ) {
- _BEHAVIOR_{set_true}
- } else {
- _BEHAVIOR_{set_false}
- }
- },
- 'set_true' => q{ _SET_VALUE_{ 1 } },
- 'set_false' => q{ _SET_VALUE_{ 0 } },
- 'set_value' => q{
- _SET_VALUE_{ scalar @_ ? shift : 1 }
- },
- },
- }
-}
-
-########################################################################
-
-=head2 bits Accessor
-
-A generic accessor for bit-field values.
-
-The difference between 'Template::Generic:bits' and
-'Template::Generic:boolean' is that all flags created with this
-meta-method are stored in a single vector for space efficiency.
-
-B<Interfaces>: The following calling interfaces are available.
-
-=over 4
-
-=item default
-
-Provides get_set behavior for I<*>, a set_I<*> method which sets
-the value to true and a clear_I<*> method which sets the value to
-false.
-
-Also defines methods named bits, bit_fields, and bit_dump with the
-behaviors below. These methods are shared across all of the boolean
-meta-methods defined by a single class.
-
-=item class_methods
-
-.
-
-=back
-
-B<Basic Behaviors>: The following types of bit-level accessor methods are available.
-
-=over 4
-
-=item get_set
-
-Returns the value of the named flag. If called with an argument, it first
-sets the named flag to the truth-value of the argument.
-
-=item set_true
-
-Sets the value to true.
-
-=item set_false
-
-Sets the value to false.
-
-=back
-
-B<Group Methods>: The following types of methods manipulate the overall vector value.
-
-=over 4
-
-=item bits
-
-Returns the vector containing all of the bit fields (remember however
-that a vector containing all 0 bits is still true).
-
-=item bit_dump
-
-Returns a hash of the flag-name/flag-value pairs.
-
-=item bits_size
-
-Returns the number of bits that can fit into the current vector.
-
-=item bits_complement
-
-Returns the twos-complement of the vector.
-
-=item bit_pos_get
-
-Takes a single argument and returns the value of the bit stored in that position.
-
-=item bit_pos_set
-
-Takes two arguments and sets the bit stored in the position of the first argument to the value of the second argument.
-
-=back
-
-B<Class Methods>: The following types of class methods are available.
-
-=over 4
-
-=item bit_names
-
-Returns a list of all the flags by name.
-
-=back
-
-=cut
-
-sub bits {
- {
- '-import' => {
- # 'Template::Generic:generic' => '*',
- },
- 'interface' => {
- default => {
- '*'=>'get_set', 'set_*'=>'set_true', 'clear_*'=>'set_false',
- 'bit_fields'=>'bit_names', 'bit_string'=>'bit_string',
- 'bit_list'=>'bit_list', 'bit_hash'=>'bit_hash',
- },
- class_methods => {
- 'bit_fields'=>'bit_names', 'bit_string'=>'bit_string',
- 'bit_list'=>'bit_list', 'bit_hash'=>'bit_hash',
- },
- },
- 'code_expr' => {
- '_VEC_POS_VALUE_{}' => 'vec(_VALUE_, *, 1)',
- _VEC_VALUE_ => '_VEC_POS_VALUE_{ _ATTR_{bfp} }',
- _CLASS_INFO_ => '$Class::MakeMethods::Template::Hash::bits{_STATIC_ATTR_{target_class}}',
- },
- 'modifier' => {
- '-all' => [ q{
- defined _VALUE_ or _VALUE_ = "";
- *
- } ],
- },
- 'behavior' => {
- '-init' => sub {
- my $m_info = $_[0];
-
- $m_info->{bfp} ||= do {
- my $array = ( $Class::MakeMethods::Template::Hash::bits{$m_info->{target_class}} ||= [] );
- my $idx;
- foreach ( 0..$#$array ) {
- if ( $array->[$_] eq $m_info->{'name'} ) { $idx = $_; last }
- }
- unless ( $idx ) {
- push @$array, $m_info->{'name'};
- $idx = $#$array;
- }
- $idx;
- };
-
- return;
- },
- 'bit_names' => q{
- @{ _CLASS_INFO_ };
- },
- 'bit_string' => q{
- if ( @_ ) {
- _SET_VALUE_{ shift @_ };
- } else {
- _VALUE_;
- }
- },
- 'bits_size' => q{
- 8 * length( _VALUE_ );
- },
- 'bits_complement' => q{
- ~ _VALUE_;
- },
- 'bit_hash' => q{
- my @bits = @{ _CLASS_INFO_ };
- if ( @_ ) {
- my %bits = @_;
- _SET_VALUE_{ pack 'b*', join '', map { $_ ? 1 : 0 } @bits{ @bits } };
- return @_;
- } else {
- map { $bits[$_], vec(_VALUE_, $_, 1) } 0 .. $#bits
- }
- },
- 'bit_list' => q{
- if ( @_ ) {
- _SET_VALUE_{ pack 'b*', join( '', map { $_ ? 1 : 0 } @_ ) };
- return map { $_ ? 1 : 0 } @_;
- } else {
- split //, unpack "b*", _VALUE_;
- }
- },
- 'bit_pos_get' => q{
- vec(_VALUE_, $_[0], 1)
- },
- 'bit_pos_set' => q{
- vec(_VALUE_, $_[0], 1) = ( $_[1] ? 1 : 0 )
- },
-
- 'get_set' => q{
- if ( @_ ) {
- _VEC_VALUE_ = ( $_[0] ? 1 : 0 );
- } else {
- _VEC_VALUE_;
- }
- },
- 'get' => q{
- _VEC_VALUE_;
- },
- 'set' => q{
- _VEC_VALUE_ = ( $_[0] ? 1 : 0 );
- },
- 'set_true' => q{
- _VEC_VALUE_ = 1;
- },
- 'set_false' => q{
- _VEC_VALUE_ = 0;
- },
-
- },
- }
-}
-
-
-########################################################################
-
-=head2 array Accessor
-
-Creates accessor methods for manipulating arrays of values.
-
-B<Interfaces>: The following calling interfaces are available.
-
-=over 4
-
-=item default
-
-Provides get_set behavior for I<*>, and I<verb>_I<*> methods for the non-get behaviors below.
-
-=item minimal
-
-Provides get_set behavior for I<*>, and I<*>_I<verb> methods for clear behavior.
-
-=item get_set_items
-
-Provides the get_set_items for I<*>.
-
-=item x_verb
-
-Provides get_push behavior for I<*>, and I<*>_I<verb> methods for the non-get behaviors below.
-
-=item get_set_ref
-
-Provides the get_set_ref for I<*>.
-
-=item get_set_ref_help
-
-Provides the get_set_ref for I<*>, and I<verb>_I<*> methods for the non-get behaviors below.
-
-=back
-
-B<Behaviors>: The following types of accessor methods are available.
-
-=over 4
-
-=item get_set_items
-
-Called with no arguments returns a reference to the array stored in the slot.
-
-Called with one simple scalar argument it treats the argument as an index
-and returns the value stored under that index.
-
-Called with more than one argument, treats them as a series of index/value
-pairs and adds them to the array.
-
-=item get_push
-
-If arguments are passed, these values are pushed on to the list; if a single array ref is passed, its values are used as the arguments.
-
-This method returns the list of values stored in the slot. In an array
-context it returns them as an array and in a scalar context as a
-reference to the array.
-
-=item get_set_ref
-
-If arguments are passed, these values are placed on the list, replacing the current contents; if a single array ref is passed, its values are used as the arguments.
-
-This method returns the list of values stored in the slot. In an array
-context it returns them as an array and in a scalar context as a
-reference to the array.
-
-=item get_set
-
-If arguments are passed, these values are placed on the list, replacing the current contents.
-
-This method returns the list of values stored in the slot. In an array
-context it returns them as an array and in a scalar context as a
-reference to the array.
-
-
-=item push
-
-Append items to tail.
-
-=item pop
-
-Remove an item from the tail.
-
-=item shift
-
-Remove an item from the front.
-
-=item unshift
-
-Prepend items to front.
-
-=item splice
-
-Remove or replace items.
-
-=item clear
-
-Remove all items.
-
-=item count
-
-Returns the number of item in the list.
-
-=back
-
-=cut
-
-sub array {
- {
- '-import' => { 'Template::Generic:generic' => '*' },
- 'interface' => {
- default => {
- '*'=>'get_set',
- map( ($_.'_*' => $_ ), qw( pop push unshift shift splice clear count )),
- map( ('*_'.$_ => $_ ), qw( ref index ) ),
- },
- minimal => { '*'=>'get_set', '*_clear'=>'clear' },
- get_set_items => { '*'=>'get_set_items' },
- x_verb => {
- '*'=>'get_set',
- map( ('*_'.$_ => $_ ), qw(pop push unshift shift splice clear count ref index )),
- },
- get_set_ref => { '*'=>'get_set_ref' },
- get_set_ref_help => { '*'=>'get_set_ref', '-base'=>'default' },
- },
- 'modifier' => {
- '-all' => [ q{ _ENSURE_REF_VALUE_; * } ],
- },
- 'code_expr' => {
- '_ENSURE_REF_VALUE_' => q{ _REF_VALUE_ ||= []; },
- },
- 'behavior' => {
- 'get_set' => q{
- @{_REF_VALUE_} = @_ if ( scalar @_ );
- return wantarray ? @{_GET_VALUE_} : _REF_VALUE_;
- },
- 'get_set_ref' => q{
- @{_REF_VALUE_} = ( ( scalar(@_) == 1 and ref($_[0]) eq 'ARRAY' ) ? @{$_[0]} : @_ ) if ( scalar @_ );
- return wantarray ? @{_GET_VALUE_} : _REF_VALUE_;
- },
- 'get_push' => q{
- push @{_REF_VALUE_}, map { ref $_ eq 'ARRAY' ? @$_ : ($_) } @_;
- return wantarray ? @{_GET_VALUE_} : _REF_VALUE_;
- },
- 'ref' => q{ _REF_VALUE_ },
- 'get' => q{ return wantarray ? @{_GET_VALUE_} : _REF_VALUE_ },
- 'set' => q{ @{_REF_VALUE_} = @_ },
- 'pop' => q{ pop @{_REF_VALUE_} },
- 'push' => q{ push @{_REF_VALUE_}, @_ },
- 'shift' => q{ shift @{_REF_VALUE_} },
- 'unshift' => q{ unshift @{_REF_VALUE_}, @_ },
- 'slice' => q{ _GET_VALUE_->[ @_ ] },
- 'splice' => q{ splice @{_REF_VALUE_}, shift, shift, @_ },
- 'count' => q{ scalar @{_GET_VALUE_} },
- 'clear' => q{ @{ _REF_VALUE_ } = () },
- 'index' => q{
- my $list = _REF_VALUE_;
- ( scalar(@_) == 1 ) ? $list->[shift]
- : wantarray ? (map $list->[$_], @_) : [map $list->[$_], @_]
- },
- 'get_set_items' => q{
- if ( scalar @_ == 0 ) {
- return _REF_VALUE_;
- } elsif ( scalar @_ == 1 ) {
- return _GET_VALUE_->[ shift() ];
- } else {
- _BEHAVIOR_{set_items}
- }
- },
- 'set_items' => q{
- ! (@_ % 2) or croak "Odd number of items in assigment to _STATIC_ATTR_{name}";
- while ( scalar @_ ) {
- my ($index, $value) = splice @_, 0, 2;
- _REF_VALUE_->[ $index ] = $value;
- }
- return _REF_VALUE_;
- },
- }
- }
-}
-
-########################################################################
-
-=head2 hash Accessor
-
-Creates accessor methods for manipulating hashes of key-value pairs.
-
-B<Interfaces>: The following calling interfaces are available.
-
-=over 4
-
-=item default
-
-Provides get_set behavior for I<*>, and I<*>_I<verb> methods for most of the other behaviors below.
-
-=item get_set_items
-
-Provides the get_set_items for I<*>.
-
-=back
-
-B<Behaviors>: The following types of accessor methods are available.
-
-=over 4
-
-=item get_set_items
-
-Called with no arguments returns a reference to the hash stored.
-
-Called with one simple scalar argument it treats the argument as a key
-and returns the value stored under that key.
-
-Called with more than one argument, treats them as a series of key/value
-pairs and adds them to the hash.
-
-=item get_push
-
-Called with no arguments returns the hash stored, as a hash
-in a list context or as a reference in a scalar context.
-
-Called with one simple scalar argument it treats the argument as a key
-and returns the value stored under that key.
-
-Called with one array reference argument, the array elements
-are considered to be be keys of the hash. x returns the list of values
-stored under those keys (also known as a I<hash slice>.)
-
-Called with one hash reference argument, the keys and values of the
-hash are added to the hash.
-
-Called with more than one argument, treats them as a series of key/value
-pairs and adds them to the hash.
-
-=item get_set
-
-Like get_push, except if called with more then one argument, empties
-the current hash items before adding those arguments to the hash.
-
-=item push
-
-Called with one hash reference argument, the keys and values of the
-hash are added to the hash.
-
-Called with more than one argument, treats them as a series of key/value
-pairs and adds them to the hash.
-
-=item keys
-
-Returns a list of the keys of the hash.
-
-=item values
-
-Returns a list of the values in the hash.
-
-=item tally
-
-Takes a list of arguments and for each scalar in the list increments the
-value stored in the hash and returns a list of the current (after the
-increment) values.
-
-=item exists
-
-Takes a single key, returns whether that key exists in the hash.
-
-=item delete
-
-Takes a list, deletes each key from the hash, and returns the corresponding values.
-
-=item clear
-
-Resets hash to empty.
-
-=back
-
-=cut
-
-sub hash {
- {
- '-import' => { 'Template::Generic:generic' => '*' },
- 'interface' => {
- 'default' => {
- '*'=>'get_set',
- map {'*_'.$_ => $_} qw(push set keys values delete exists tally clear),
- },
- get_set_items => { '*'=>'get_set_items' },
- },
- 'modifier' => {
- '-all' => [ q{ _ENSURE_REF_VALUE_; * } ],
- },
- 'code_expr' => {
- '_ENSURE_REF_VALUE_' => q{ _REF_VALUE_ ||= {}; },
- _HASH_GET_ => q{
- ( wantarray ? %{_GET_VALUE_} : _REF_VALUE_ )
- },
- _HASH_GET_VALUE_ => q{
- ( ref $_[0] eq 'ARRAY' ? @{ _GET_VALUE_ }{ @{ $_[0] } }
- : _REF_VALUE_->{ $_[0] } )
- },
- _HASH_SET_ => q{
- ! (@_ % 2) or croak "Odd number of items in assigment to _STATIC_ATTR_{name}";
- %{_REF_VALUE_} = @_
- },
- _HASH_PUSH_ => q{
- ! (@_ % 2)
- or croak "Odd number of items in assigment to _STATIC_ATTR_{name}";
- my $count;
- while ( scalar @_ ) {
- local $_ = shift;
- _REF_VALUE_->{ $_ } = shift();
- ++ $count;
- }
- $count;
- },
- },
- 'behavior' => {
- 'get_set' => q {
- # If called with no arguments, return hash contents
- return _HASH_GET_ if (scalar @_ == 0);
-
- # If called with a hash ref, act as if contents of hash were passed
- # local @_ = %{ $_[0] } if ( scalar @_ == 1 and ref $_[0] eq 'HASH' );
- @_ = %{ $_[0] } if ( scalar @_ == 1 and ref $_[0] eq 'HASH' );
-
- # If called with an index, get that value, or a slice for array refs
- return _HASH_GET_VALUE_ if (scalar @_ == 1 );
-
- # Push on new values and return complete set
- _HASH_SET_;
- return _HASH_GET_;
- },
-
- 'get_push' => q{
- # If called with no arguments, return hash contents
- return _HASH_GET_ if (scalar @_ == 0);
-
- # If called with a hash ref, act as if contents of hash were passed
- # local @_ = %{ $_[0] } if ( scalar @_ == 1 and ref $_[0] eq 'HASH' );
- @_ = %{ $_[0] } if ( scalar @_ == 1 and ref $_[0] eq 'HASH' );
-
- # If called with an index, get that value, or a slice for array refs
- return _HASH_GET_VALUE_ if (scalar @_ == 1 );
-
- # Push on new values and return complete set
- _HASH_PUSH_;
- return _HASH_GET_;
- },
- 'get_set_items' => q{
- if ( scalar @_ == 0 ) {
- return _REF_VALUE_;
- } elsif ( scalar @_ == 1 ) {
- return _REF_VALUE_->{ shift() };
- } else {
- while ( scalar @_ ) {
- my ($index, $value) = splice @_, 0, 2;
- _REF_VALUE_->{ $index } = $value;
- }
- return _REF_VALUE_;
- }
- },
- 'get' => q{ _HASH_GET_ },
- 'set' => q{ _HASH_SET_ },
- 'push' => q{
- # If called with a hash ref, act as if contents of hash were passed
- # local @_ = %{ $_[0] } if ( scalar @_ == 1 and ref $_[0] eq 'HASH' );
- @_ = %{ $_[0] } if ( scalar @_ == 1 and ref $_[0] eq 'HASH' );
-
- _HASH_PUSH_
- },
-
- 'keys' => q{ keys %{_GET_VALUE_} },
- 'values' => q{ values %{_GET_VALUE_} },
- 'unique_values' => q{
- values %{ { map { $_=>$_ } values %{_GET_VALUE_} } }
- },
- 'delete' => q{ scalar @_ <= 1 ? delete @{ _REF_VALUE_ }{ $_[0] }
- : map { delete @{ _REF_VALUE_ }{ $_ } } (@_) },
- 'exists' => q{
- return 0 unless defined _GET_VALUE_;
- foreach (@_) { return 0 unless exists ( _REF_VALUE_->{$_} ) }
- return 1;
- },
- 'tally' => q{ map { ++ _REF_VALUE_->{$_} } @_ },
- 'clear' => q{ %{ _REF_VALUE_ } = () },
- 'ref' => q{ _REF_VALUE_ },
- },
- }
-}
-
-########################################################################
-
-=head2 tiedhash Accessor
-
-A variant of Generic:hash which initializes the hash by tieing it to a caller-specified package.
-
-See the documentation on C<Generic:hash> for interfaces and behaviors.
-
-B<Parameters>: The following parameters I<must> be provided:
-
-=over 4
-
-=item tie
-
-I<Required>. The name of the class to tie to.
-I<Make sure you have C<use>d the required class>.
-
-=item args
-
-I<Required>. Additional arguments for the tie, as an array ref.
-
-=back
-
-Example:
-
- use Class::MakeMethods
- tie_hash => [ hits => { tie => q/Tie::RefHash/, args => [] } ];
-
- use Class::MakeMethods
- tie_hash => [ [qw(hits errors)] => { tie => q/Tie::RefHash/, args => [] } ];
-
- use Class::MakeMethods
- tie_hash => [ { name => hits, tie => q/Tie::RefHash/, args => [] } ];
-
-=cut
-
-sub tiedhash {
- {
- '-import' => { 'Template::Generic:hash' => '*' },
- 'modifier' => {
- '-all' => [ q{
- if ( ! defined _GET_VALUE_ ) {
- %{ _REF_VALUE_ } = ();
- tie %{ _REF_VALUE_ }, _ATTR_REQUIRED_{tie}, @{ _ATTR_{args} };
- }
- *
- } ],
- },
- }
-}
-
-########################################################################
-
-=head2 hash_of_arrays Accessor
-
-Creates accessor methods for manipulating hashes of array-refs.
-
-B<Interfaces>: The following calling interfaces are available.
-
-=over 4
-
-=item default
-
-Provides get behavior for I<*>, and I<*>_I<verb> methods for the other behaviors below.
-
-=back
-
-B<Behaviors>: The following types of accessor methods are available.
-
-=over 4
-
-=item get
-
-Returns all the values for all the given keys, in order. If no keys are
-given, returns all the values (in an unspecified key order).
-
-The result is returned as an arrayref in scalar context. This arrayref
-is I<not> part of the data structure; messing with it will not affect
-the contents directly (even if a single key was provided as argument.)
-
-If any argument is provided which is an arrayref, then the members of
-that array are used as keys. Thus, the trivial empty-key case may be
-utilized with an argument of [].
-
-=item keys
-
-Returns the keys of the hash. As an arrayref in scalar context.
-
-=item exists
-
-Takes a list of keys, and returns whether all of the key exists in the hash
-(i.e., the C<and> of whether the individual keys exist).
-
-=item delete
-
-Takes a list, deletes each key from the hash.
-
-=item push
-
-Takes a key, and some values. Pushes the values onto the list denoted
-by the key. If the first argument is an arrayref, then each element of
-that arrayref is treated as a key and the elements pushed onto each
-appropriate list.
-
-=item pop
-
-Takes a list of keys, and pops each one. Returns the list of popped
-elements. undef is returned in the list for each key that is has an
-empty list.
-
-=item unshift
-
-Like push, only the from the other end of the lists.
-
-=item shift
-
-Like pop, only the from the other end of the lists.
-
-=item splice
-
-Takes a key, offset, length, and a values list. Splices the list named
-by the key. Anything from the offset argument (inclusive) may be
-omitted. See L<perlfunc/splice>.
-
-=item clear
-
-Takes a list of keys. Resets each named list to empty (but does not
-delete the keys.)
-
-=item count
-
-Takes a list of keys. Returns the sum of the number of elements for
-each named list.
-
-=item index
-
-Takes a key, and a list of indices. Returns a list of each item at the
-corresponding index in the list of the given key. Uses undef for
-indices beyond range.
-
-=item remove
-
-Takes a key, and a list of indices. Removes each corresponding item
-from the named list. The indices are effectively looked up at the point
-of call -- thus removing indices 3, 1 from list (a, b, c, d) will
-remove (d) and (b).
-
-=item sift
-
-Takes a key, and a set of named arguments, which may be a list or a hash
-ref. Removes list members based on a grep-like approach.
-
-=over 4
-
-=item filter
-
-The filter function used (as a coderef). Is passed two arguments, the
-value compared against, and the value in the list that is potential for
-grepping out. If returns true, the value is removed. Default is C<sub { $_[0] == $_[1] }>.
-
-=item keys
-
-The list keys to sift through (as an arrayref). Unknown keys are
-ignored. Default: all the known keys.
-
-=item values
-
-The values to sift out (as an arrayref). Default: C<[undef]>
-
-=back
-
-=back
-
-=cut
-
-sub hash_of_arrays {
- {
- '-import' => { 'Template::Generic:hash' => '*' },
- 'interface' => {
- default => {
- '*'=>'get',
- map( ('*_'.$_ => $_ ), qw(keys exists delete pop push shift unshift splice clear count index remove sift last set )),
- },
- },
- 'behavior' => {
- 'get' => q{
- my @Result;
-
- if ( ! scalar @_ ) {
- @Result = map @$_, values %{_VALUE_};
- } elsif ( scalar @_ == 1 and ref ($_[0]) eq 'ARRAY' ) {
- @Result = map @$_, @{_VALUE_}{@{$_[0]}};
- } else {
- my @keys = map { ref ($_) eq 'ARRAY' ? @$_ : $_ }
- grep exists _VALUE_{$_}, @_;
- @Result = map @$_, @{_VALUE_}{@keys};
- }
-
- return wantarray ? @Result : \@Result;
- },
- 'pop' => q{
- map { pop @{_VALUE_->{$_}} } @_
- },
- 'last' => q{
- map { _VALUE_->{$_}->[-1] } @_
- },
- 'push' => q{
- for ( ( ref ($_[0]) eq 'ARRAY' ? @{shift()} : shift() ) ) {
- push @{_VALUE_->{$_}}, @_;
- }
- },
- 'shift' => q{
- map { shift @{_VALUE_->{$_}} } @_
- },
- 'unshift' => q{
- for ( ( ref ($_[0]) eq 'ARRAY' ? @{shift()} : shift() ) ) {
- unshift @{_VALUE_->{$_}}, @_;
- }
- },
- 'splice' => q{
- my $key = shift;
- splice @{ _VALUE_->{$key} }, shift, shift, @_;
- },
- 'clear' => q{
- foreach (@_) { _VALUE_->{$_} = []; }
- },
- 'count' => q{
- my $Result = 0;
- foreach (@_) {
- # Avoid autovivifying additional entries.
- $Result += exists _VALUE_->{$_} ? scalar @{_VALUE_->{$_}} : 0;
- }
- return $Result;
- },
- 'index' => q{
- my $key_r = shift;
-
- my @Result;
- my $key;
- foreach $key ( ( ref ($key_r) eq 'ARRAY' ? @$key_r : $key_r ) ) {
- my $ary = _VALUE_->{$key};
- for (@_) {
- push @Result, ( @{$ary} > $_ ) ? $ary->[$_] : undef;
- }
- }
- return wantarray ? @Result : \@Result;
- },
- 'set' => q{
- my $key_r = shift;
-
- croak "_ATTR_{name} expects a key and then index => value pairs.\n"
- if @_ % 2;
- while ( scalar @_ ) {
- my $pos = shift;
- _VALUE_->{$key_r}->[ $pos ] = shift();
- }
- return;
- },
- 'remove' => q{
- my $key_r = shift;
-
- my $key;
- foreach $key ( ( ref ($key_r) eq 'ARRAY' ? @$key_r : $key_r ) ) {
- my $ary = _VALUE_->{$key};
- foreach ( sort {$b<=>$a} grep $_ < @$ary, @_ ) {
- splice (@$ary, $_, 1);
- }
- }
- return;
- },
- 'sift' => q{
- my %args = ( scalar @_ == 1 and ref $_[0] eq 'HASH' ) ? %{$_[0]} : @_;
- my $hash = _VALUE_;
- my $filter_sr = $args{'filter'} || sub { $_[0] == $_[1] };
- my $keys_ar = $args{'keys'} || [ keys %$hash ];
- my $values_ar = $args{'values'} || [undef];
-
- # This is harder than it looks; reverse means we want to grep out only
- # if *none* of the values matches. I guess an evaled block, or closure
- # or somesuch is called for.
- # my $reverse = $args{'reverse'} || 0;
-
- my ($key, $i, $value);
- KEY: foreach $key (@$keys_ar) {
- next KEY unless exists $hash->{$key};
- INDEX: for ($i = $#{$hash->{$key}}; $i >= 0; $i--) {
- foreach $value (@$values_ar) {
- if ( $filter_sr->($value, $hash->{$key}[$i]) ) {
- splice @{$hash->{$key}}, $i, 1;
- next INDEX;
- }
- }
- }
- }
- return;
- },
- },
- }
-}
-
-########################################################################
-
-=head2 object Accessor
-
-Creates accessor methods for manipulating references to objects.
-
-In addition to creating a method to get and set the object reference,
-the meta-method can also define forwarded methods that automatically
-pass calls onto the object stored in that slot; see the description of the 'delegate' parameter below.
-
-B<Interfaces>: The following calling interfaces are available.
-
-=over 4
-
-=item default
-
-Provides get_set behavior for I<*>, clear behavior for 'delete_*',
-and forwarding methods for any values in the method's 'delegate'
-or 'soft_delegate' parameters.
-
-=item get_and_set
-
-Provides named get method, set_I<x> and clear_I<x> methods.
-
-=item get_init_and_set
-
-Provides named get_init method, set_I<x> and clear_I<x> methods.
-
-=back
-
-B<Behaviors>: The following types of accessor methods are available.
-
-=over 4
-
-=item get_set
-
-The get_set method, if called with a reference to an object of the
-given class as the first argument, stores it.
-
-If called with any other arguments, creates and stores a new object, passing the arguemnts to the new() method for the object.
-
-If called without arguments, returns the current value, which may be undefined if one has not been stored yet.
-
-=item get_set_init
-
-The get_set_init method, if called with a reference to an object of the
-given class as the first argument, stores it.
-
-If the slot is not filled yet it creates an object by calling the given
-new method of the given class. Any arguments passed to the get_set_init
-method are passed on to new.
-
-In all cases the object now stored is returned.
-
-=item get_init
-
-If the instance is empty, creates and stores a new one. Returns the instance.
-
-=item get
-
-Returns the current value, which may be undefined if one has not been stored yet.
-
-=item set
-
-If called with a reference to an object of the given class as the first argument, stores it.
-
-If called with any other arguments, creates and stores a new object, passing the arguments to the new() method.
-
-If called without arguments, creates and stores a new object, without any arguments to the new() method.
-
-=item clear
-
-Removes the reference value.
-
-=item I<forwarding>
-
-If a 'delegate' or 'soft_delegate' parameter is provided, methods
-with those names are created that are forwarded directly to the
-object in the slot, as described below.
-
-=back
-
-B<Parameters>: The following parameters are supported:
-
-=over 4
-
-=item class
-
-I<Required>. The type of object that will be stored.
-
-=item new_method
-
-The name of the method to call on the above class to create a new instance. Defaults to 'new'.
-
-=item delegate
-
-The methods to forward to the object. Can contain a method name,
-a string of space-spearated method names, or an array of method
-names. This type of method will croak if it is called when the
-target object is not defined.
-
-=item soft_delegate
-
-The methods to forward to the object, if it is present. Can contain
-a method name, a string of space-spearated method names, or an
-array of method names. This type of method will return nothing if
-it is called when the target object is not defined.
-
-=back
-
-=cut
-
-sub object {
- {
- '-import' => {
- # 'Template::Generic:generic' => '*',
- },
- 'interface' => {
- default => { '*'=>'get_set', 'clear_*'=>'clear' },
- get_set_init => { '*'=>'get_set_init', 'clear_*'=>'clear' },
- get_and_set => {'*'=>'get', 'set_*'=>'set', 'clear_*'=>'clear' },
- get_init_and_set => { '*'=>'get_init','set_*'=>'set','clear_*'=>'clear' },
- init_and_get => { '*'=>'init_and_get', -params=>{ init_method=>'init_*' } },
- },
- 'params' => {
- new_method => 'new'
- },
- 'code_expr' => {
- '_CALL_NEW_AND_STORE_' => q{
- my $new_method = _ATTR_REQUIRED_{new_method};
- my $class = _ATTR_REQUIRED_{'class'};
- _SET_VALUE_{ $class->$new_method(@_) };
- },
- },
- 'behavior' => {
- '-import' => {
- 'Template::Generic:scalar' => [ qw( get clear ) ],
- },
- 'get_set' => q{
- if ( scalar @_ ) {
- if (ref $_[0] and UNIVERSAL::isa($_[0], _ATTR_REQUIRED_{'class'})) {
- _SET_VALUE_{ shift };
- } else {
- _CALL_NEW_AND_STORE_
- }
- } else {
- _VALUE_;
- }
- },
- 'set' => q{
- if ( ! defined $_[0] ) {
- _SET_VALUE_{ undef };
- } elsif (ref $_[0] and UNIVERSAL::isa($_[0], _ATTR_REQUIRED_{'class'})) {
- _SET_VALUE_{ shift };
- } else {
- _CALL_NEW_AND_STORE_
- }
- },
- 'get_init' => q{
- if ( ! defined _VALUE_ ) {
- _CALL_NEW_AND_STORE_
- }
- _VALUE_;
- },
- 'init_and_get' => q{
- if ( ! defined _VALUE_ ) {
- my $init_method = _ATTR_REQUIRED_{'init_method'};
- _SET_VALUE_{ _SELF_->$init_method( @_ ) };
- } else {
- _BEHAVIOR_{get}
- }
- },
- 'get_set_init' => q{
- if (ref $_[0] and UNIVERSAL::isa($_[0], _ATTR_REQUIRED_{'class'})) {
- _SET_VALUE_{ shift };
- } elsif ( ! defined _VALUE_ ) {
- _CALL_NEW_AND_STORE_
- }
- _VALUE_;
- },
- '-subs' => sub {
- {
- 'delegate' => sub { my($m_info, $name) = @_; sub {
- my $m_name = $m_info->{'name'};
- my $obj = (shift)->$m_name()
- or Carp::croak("Can't forward $name because $m_name is empty");
- $obj->$name(@_)
- } },
- 'soft_delegate' => sub { my($m_info, $name) = @_; sub {
- my $m_name = $m_info->{'name'};
- my $obj = (shift)->$m_name() or return;
- $obj->$name(@_)
- } },
- }
- },
- },
- }
-}
-
-########################################################################
-
-=head2 instance Accessor
-
-Creates methods to handle an instance of the calling class.
-
-PROFILES
-
-=over 4
-
-=item default
-
-Provides named get method, and I<verb>_I<x> set, new, and clear methods.
-
-=item -implicit_new
-
-Provides named get_init method, and I<verb>_I<x> set, and clear methods.
-
-=item -x_verb
-
-Provides named get method, and I<x>_I<verb> set, new, and clear methods.
-
-=back
-
-B<Behaviors>: The following types of accessor methods are available.
-
-=over 4
-
-=item get
-
-Returns the value of the instance parameter, which may be undefined if one has not been stored yet.
-
-=item get_init
-
-If the instance is empty, creates and stores a new one. Returns the instance.
-
-=item set
-
-Takes a single argument and sets the instance to that value.
-
-=item new
-
-Creates and stores a new instance.
-
-=item clear
-
-Sets the instance parameter to undef.
-
-=back
-
-B<Parameters>: The following parameters are supported:
-
-=over 4
-
-=item instance
-
-Holds the instance reference. Defaults to undef
-
-=item new_method
-
-The name of the method to call when creating a new instance. Defaults to 'new'.
-
-=back
-
-=cut
-
-sub instance {
- {
- '-import' => {
- 'Template::Generic:object' => '*',
- },
- 'interface' => {
- default => 'get_set',
- },
- 'code_expr' => {
- '_CALL_NEW_AND_STORE_' => q{
- my $new_method = _ATTR_REQUIRED_{new_method};
- _SET_VALUE_{ (_SELF_)->$new_method(@_) };
- },
- },
- }
-}
-
-########################################################################
-
-=head2 array_of_objects Accessor
-
-Creates accessor methods for manipulating references to arrays of object references.
-
-Operates like C<Generic:array>, but prior to adding any item to
-the array, it first checks to see if it is an instance of the
-designated class, and if not passes it as an argument to that
-class's new method and stores the result instead.
-
-Forwarded methods return a list of the results returned
-by C<map>ing the method over each object in the array.
-
-See the documentation on C<Generic:array> for interfaces and behaviors.
-
-B<Parameters>: The following parameters are supported:
-
-=over 4
-
-=item class
-
-I<Required>. The type of object that will be stored.
-
-=item delegate
-
-The methods to forward to the object. Can contain a method name, a string of space-spearated method names, or an array of method names.
-
-=item new_method
-
-The name of the method to call on the above class to create a new instance. Defaults to 'new'.
-
-=back
-
-=cut
-
-sub array_of_objects {
- {
- '-import' => {
- 'Template::Generic:array' => '*',
- },
- 'params' => {
- new_method => 'new',
- },
- 'modifier' => {
- '-all get_set' => q{ _BLESS_ARGS_ * },
- '-all get_push' => q{ _BLESS_ARGS_ * },
- '-all set' => q{ _BLESS_ARGS_ * },
- '-all push' => q{ _BLESS_ARGS_ * },
- '-all unshift' => q{ _BLESS_ARGS_ * },
- # The below two methods are kinda broken, because the new values
- # don't get auto-blessed properly...
- '-all splice' => q{ * },
- '-all set_items' => q{ * },
- },
- 'code_expr' => {
- '_BLESS_ARGS_' => q{
- my $new_method = _ATTR_REQUIRED_{'new_method'};
- @_ = map {
- (ref $_ and UNIVERSAL::isa($_, _ATTR_REQUIRED_{class})) ? $_
- : _ATTR_{'class'}->$new_method($_)
- } @_;
- },
- },
- 'behavior' => {
- '-subs' => sub {
- {
- 'delegate' => sub { my($m_info, $name) = @_; sub {
- my $m_name = $m_info->{'name'};
- map { $_->$name(@_) } (shift)->$m_name()
- } },
- }
- },
- },
- }
-}
-
-########################################################################
-
-=head2 code Accessor
-
-Creates accessor methods for manipulating references to subroutines.
-
-B<Interfaces>: The following calling interfaces are available.
-
-=over 4
-
-=item default
-
-Provides the call_set functionality.
-
-=item method
-
-Provides the call_method functionality.
-
-=back
-
-B<Behaviors>: The following types of accessor methods are available.
-
-=over 4
-
-=item call_set
-
-If called with one argument which is a CODE reference, it installs that
-code in the slot. Otherwise it runs the code stored in the slot with
-whatever arguments (including none) were passed in.
-
-=item call_method
-
-Just like B<call_set>, except the code is called like a method, with $self
-as its first argument. Basically, you are creating a method which can be
-different for each object.
-
-=back
-
-=cut
-
-sub code {
- {
- '-import' => {
- # 'Template::Generic:generic' => '*',
- },
- 'interface' => {
- default => 'call_set',
- call_set => 'call_set',
- method => 'call_method',
- },
- 'behavior' => {
- '-import' => {
- 'Template::Generic:scalar' => [ qw( get_set get set clear ) ],
- },
- 'call_set' => q{
- if ( scalar @_ == 1 and ref($_[0]) eq 'CODE') {
- _SET_VALUE_{ shift }; # Set the subroutine reference
- } else {
- &{ _VALUE_ }( @_ ); # Run the subroutine on the given arguments
- }
- },
- 'call_method' => q{
- if ( scalar @_ == 1 and ref($_[0]) eq 'CODE') {
- _SET_VALUE_{ shift }; # Set the subroutine reference
- } else {
- &{ _VALUE_ }( _SELF_, @_ ); # Run the subroutine on self and args
- }
- },
- },
- }
-}
-
-
-########################################################################
-
-=head2 code_or_scalar Accessor
-
-Creates accessor methods for manipulating either strings or references to subroutines.
-
-You can store any scalar value; code refs are executed when you retrieve the value, while other scalars are returned as-is.
-
-B<Interfaces>: The following calling interfaces are available.
-
-=over 4
-
-=item default
-
-Provides the call_set functionality.
-
-=item method
-
-Provides the call_method functionality.
-
-=item eiffel
-
-Provides the named get_method, and a helper set_* method.
-
-=back
-
-B<Behaviors>: The following types of accessor methods are available.
-
-=over 4
-
-=item get_set_call
-
-If called with an argument, either a CODE reference or some other scalar, it installs that code in the slot. Otherwise, if the current value runs the code stored in the slot with
-whatever arguments (including none) were passed in.
-
-=item get_set_method
-
-Just like B<call_set>, except the code is called like a method, with $self
-as its first argument. Basically, you are creating a method which can be
-different for each object.
-
-=back
-
-=cut
-
-sub code_or_scalar {
- {
- '-import' => { 'Template::Generic:scalar' => '*' },
- 'interface' => {
- default => 'get_set_call',
- get_set => 'get_set_call',
- eiffel => { '*'=>'get_method', 'set_*'=>'set' },
- method => 'get_set_method',
- },
- 'params' => {
- },
- 'behavior' => {
- 'get_call' => q{
- my $value = _GET_VALUE_;
- ( ref($value) eq 'CODE' ) ? &$value( @_ ) : $value
- },
- 'get_method' => q{
- my $value = _GET_VALUE_;
- ( ref($value) eq 'CODE' ) ? &$value( _SELF_, @_ ) : $value
- },
- 'get_set_call' => q{
- if ( scalar @_ == 1 ) {
- _BEHAVIOR_{set}
- } else {
- _BEHAVIOR_{get_call}
- }
- },
- 'get_set_method' => q{
- if ( scalar @_ == 1 ) {
- _BEHAVIOR_{set}
- } else {
- _BEHAVIOR_{get_call}
- }
- },
- },
- }
-}
-
-
-########################################################################
-
-=head1 SEE ALSO
-
-See L<Class::MakeMethods> for general information about this distribution.
-
-See L<Class::MakeMethods::Template> for information about this family of subclasses.
-
-=cut
-
-1;