Class-MethodMaker

 view release on metacpan or  search on metacpan

lib/Class/MethodMaker.pm  view on Meta::CPAN

of types of generic methods generated by MethodMaker and whose "values" tell
method maker what methods to make.

To override any generated methods, it is sufficient to ensure that the
overriding method is defined when Class::MethodMaker is called.  Note
that the C<use> keyword introduces a C<BEGIN> block, so you may need to
define (or at least declare) your overriding method in a C<BEGIN> block.

=head2 Simple Use

A simple class made with C<Class::MethodMaker> looks like this:

  package MyClass;

  use Class::MethodMaker
    [ scalar => [qw/ name /],
      new    => [qw/ new  /],
    ];

This creates a class, of which new instances may be created using C<new>, each
with a single scalar component called C<name>.  Name may be queried and (re)set
using the methods C<name>, C<name_reset> and C<name_isset>:

  package main;

  my $m = MyClass->new;
  my $n;
  $\ = "\n";

  print $m->name_isset ? "true" : "false";     # false

  $m->name("foo");
  $n = $m->name;
  print defined $n ? "->$n<-" : "*undef*";     # ->foo<-
  print $m->name_isset ? "true" : "false";     # true

  $m->name(undef);
  $n = $m->name;
  print defined $n ? "->$n<-" : "*undef*";     # *undef*
  print $m->name_isset ? "true" : "false";     # true

  $m->name_reset;
  $n = $m->name;
  print defined $n ? "->$n<-" : "*undef*";     # *undef*
  print $m->name_isset ? "true" : "false";     # false

The available component types are L<scalar|Class::MethodMaker::scalar>,
L<array|Class::MethodMaker::array>, L<hash|Class::MethodMaker::hash>.  Certain
non-data-type utilities are also provided:
L<new|Class::MethodMaker::Engine/new>, for constructors,
L<deep_copy|Class::MethodMaker::Engine/deep_copy> and
L<copy|Class::MethodMaker::Engine/copy> for object copies, and
L<abstract|Class::MethodMaker::Engine/abstract> for creating abstract methods.

Each of the components take common options.  These include L<-static>, for
per-class rather than per-instance data, L<-type>, to restrict the data stored
to certain types (e.g., objects of a certain class), L<-forward> to forward
(proxy) given methods onto components, L<-default>/L<-default_ctor> to set
default values for components, L<-tie_class> to tie the storage of a data type
to a given class, L<-read_cb>/L<-store_cb> to call user-defined functions on
read/store (without the overhead/complexity of ties; and allowing callbacks on
existing tie classes).

=head2 Detailed Use

C<Class::MethodMaker> installs I<components> into a class, by means of methods
that interrogate and amend those components.  A component, sometimes referred
in other documentation as a I<slot> is a group of one or more attributes
(variables) that are associated with an instance of a class (sometimes called
an object), or occasionally a class itself (often referred to as a I<static>
component).  A component is intended as a cohesive unit of data that should
only normally be interrogated or set through the methods provided.

Given an instance of a class where each instance represents a car, examples of
components are the C<make> and C<model> (each of which would be a simple
scalar, a string), the engine (a simple scalar, an instance of
Engine::Combustion), and the wheels (an array of instances of Wheel).  Note
that the wheels form one component, an array.  Of course, the implementor
might instead choose to use four components, each being a scalar wheel.

To have the components created, the principle use of Class::MethodMaker is to
specify the type (data-structure) and name of each component to the import
method of Class::MethodMaker

  package MyClass;

  use Class::MethodMaker
    [ scalar => 'name',
      new    => [qw/ new /],
    ];

In this example, the import is called implicitly via the C<use> statement.
The components are installed in the package in effect where the import is
called.  The argument to import is arranged as pairs, where the first of each
pair is the type of the data-structure, the second is the arguments for that
data-structure; in the most simple case, the name of a component to install
using that data-structure.  The second of the pair should be an arrayref if
not a simple name.

Data-structures may be repeated in the call:

  use Class::MethodMaker
    [ scalar => 'name1',
      new    => [qw/ new /],
      scalar => 'name2',
    ];

It is an error to attempt to install a two or more components with the same
name twice.

Options may be given to data structures to amend the nature and behaviour of
the components created.  Some options are common across all data structure
(e.g., C<static>) whilst some are specific to their respective data
structures.  Option syntax is laid out in detail below.  In simple, options
are provided by way of hashrefs from option name to option value.  Options and
component names are order-sensitive; options appearing after a component do
not affect that component.  Options only apply to the data-structure to which
they are specified.  B<Boolean> options (e.g., static) may be abbreviated to
-option to set, !option to unset, without a hashref.

  use Class::MethodMaker

lib/Class/MethodMaker.pm  view on Meta::CPAN

                 },
                 qw( tie2 ),
                ]]);

This option takes an array reference, whose members are passed as arguments to
any tie invoked on the component (by virtue C<-tie_class>).  If C<-tie_class>
is not in force, this is ignored.

As a convenience measure, a single argument may be passed directly, rather
than embedding in an array ref --- unless that arg is an array ref itself...

=item -read_cb

B<The implementation of this option is incomplete>

  package MyClass;
  use Class::MethodMaker
    [ scalar => [{ -read_cb => sub { ($_[1]||0) + 1 } }, 'rcb1' ]
      new    => 'new';
    ];

This option takes as argument a coderef, which is called whenever a value is
read.  It is called with two arguments: the instance upon which the method was
called, and the value stored in the component.  The return value of the given
coderef is the value which is passed to the caller of the method as the
component value.  Thus, the above example adds one to whatever the stored
value is.  Note that the value is returned to the callee, but not stored in
the object

  package main;
  my $m = MyClass->new;
  $m->rcb1(4);
  my $n = $x->rcb1; # 5
  my $n = $x->rcb1; # 5

=item -store_cb

B<The implementation of this option is incomplete>

  package MyClass;
  use Class::MethodMaker
    [ scalar => [{ -store_cb => sub { $_[1] + 1 } }, 'scb1' ]
      new    => 'new';
    ];

This option takes as argument a coderef, which is called whenever a value is
stored.  It is called with four arguments: the instance upon which the method
was called, the value to store in the component, the name of the component,
and the previous value of the component (if any; if the given element of the
component was previously unset, only three arguments are passed).

The return value of the given coderef is the value which is actually stored in
the component.  Thus, the above example stores 1 greater than the value passed
in.

  package main;
  my $m = MyClass->new;
  $m->scb1(4);
  my $n = $x->scb1; # 5

Generally, store callbacks are cheaper than read callbacks, because values are
read more often than they are stored.  But that is a generalization.  YMMV.

=back

=head1 EXPERIMENTAL & COMPATIBILITY notes

Some new facilities may be marked as EXPERIMENTAL in the documentation.
These facilities are being trialled, and whilst it is hoped that they
will become mainstream code, no promises are made.  They may change or
disappear at any time.  Caveat Emptor.  The maintainer would be
delighted to hear any feedback particularly regarding such facilities,
be it good or bad, so long as it is constructive.

Some old facilities may be marked as COMPATIBILITY in the documentation.
These facilities are being maintained purely for compatibility with old
versions of this module, but will ultimately disappear.  They are normally
replaced by alternatives that are considered preferable.  Please avoid using
them, and consider amending any existing code that does use them not to.  If
you believe that their removal will cast an unacceptable pall over your life,
please contact the maintainer.

=head1 SEE ALSO

L<Class::MethodMaker::Engine>, L<Class::MethodMaker::scalar>,
L<Class::MethodMaker::array>, L<Class::MethodMaker::hash>,
L<Class::MethodMaker::V1Compat>

=cut



( run in 0.798 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )