Class::MethodMaker man page on Scientific

Man page or keyword search:  
man Server   26626 pages
apropos Keyword Search (all sections)
Output format
Scientific logo
[printable version]

Class::MethodMaker(3) User Contributed Perl DocumentationClass::MethodMaker(3)

NAME
       Class::MethodMaker - Create generic methods for OO Perl

SYNOPSIS
	 use Class::MethodMaker
	   [ scalar => [qw/ foo bar baz /],
	     new    => [qw/ new /]	  ,
	   ];

DESCRIPTION
       This module solves the problem of having to continually write accessor
       methods for your objects that perform standard tasks.

       The argument to 'use' is an arrayref, as pairs whose "keys" are the
       names 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 "use" keyword introduces a "BEGIN" block, so you may need to
       define (or at least declare) your overriding method in a "BEGIN" block.

   Simple Use
       A simple class made with "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
       "new", each with a single scalar component called "name".  Name may be
       queried and (re)set using the methods "name", "name_reset" and
       "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 scalar, array, hash.  Certain non-
       data-type utilities are also provided: new, for constructors, deep_copy
       and copy for object copies, and abstract for creating abstract methods.

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

   Detailed Use
       "Class::MethodMaker" installs components into a class, by means of
       methods that interrogate and amend those components.  A component,
       sometimes referred in other documentation as a 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 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 "make" and "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 "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., "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.	 Boolean
       options (e.g., static) may be abbreviated to -option to set, !option to
       unset, without a hashref.

	 use Class::MethodMaker
	   [ scalar => [+{ -type => 'File::stat' }, qw/ -static name /],
	     new    => 'new',
	   ];

       There are also non-data-structure methods that may be created by
       Class::MethodMaker.  "new" is an example of one such value; it instead
       causes a standard "new" method to be created for the calling class.
       The arguments and options syntax remains the same, but many options
       clearly do not apply (e.g., "type" for "new").

   Interaction with Superclasses
       Basically, "Class::MethodMaker" takes no notice of class hierarchies.
       If you choose to install a component x in a class B that is a subclass
       of class A that already has a component x, then the methods addressing
       x in B will simply override those in class A in the usual fashion.
       "Class::MethodMaker" takes no special action for this situation.	 This
       is a feature.

   Option Syntax
       The arguments to Class::MethodMaker are passed in a single arrayref, as
       pairs, with the first of each pair being the name of the data-
       structure, and the second being the arguments to that structure.

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

       The second of the pair may in the most simple case be a single scalar
       that is the name of a component to use.

	 use Class::MethodMaker
	   [ scalar => 'bob', ];

       For anything more complex, the second argument must itself be an
       arrayreference.	Simple names within this arrayreference are again
       taken as component names to use; in the following example, both "foo"
       and "bar" scalar components are created:

	 use Class::MethodMaker
	   [ scalar => [qw/ foo bar /], ];

       Options to the data-structure, to change the behaviour of the
       component, or methods available, etc., are specified by the presence of
       a hash reference in line with the component names.  Each key of the
       hashref is the name of an option; the corresponding value is the option
       value.  Option names are easily recognized by a leading hyphen ("-")
       (or leading exclamation mark, "!").  The options affect only the
       components named after the option itself.  In the following example,
       "foo" is non-static (the default), whilst bar is a static:

	 use Class::MethodMaker
	   [ scalar => ['foo', { -static => 1 }, 'bar'], ];

       Naturally, options may be altered by later settings overriding earlier
       ones.  The example below has exactly the same effect as the one above:

	 use Class::MethodMaker
	   [ scalar => [{ -static => 1 }, 'bar', { -static => 0 }, 'foo'], ];

       Options that are boolean (on/off) valued, such as "-static", may be
       specified external to any hashref as "-optionname" to set them on and
       "!optionname" to set them off.  The example below has exactly the same
       effect as the one above:

	 use Class::MethodMaker
	   [ scalar => [ qw/ -static bar !static foo /], ];

       Options that take a value, e.g., "-type", must be specified within a
       hashref:

	 use Class::MethodMaker
	   [ scalar => [ +{ type => 'File::stat' }, 'bob' ], ];

       Options affect is limited by the scope of the nearest enclosing
       arrayref.  This particularly means that for multiple invocations of a
       data structure type, options on earlier invocations do not affect later
       ones.  In the following example, "foo" is non-static (the default),
       whilst bar is a static:

	 use Class::MethodMaker
	   [ scalar => [ qw/ -static bar /],
	     scalar => [ 'foo' ],
	   ];

       This is true even if later invocations do not use an arrayref.  The
       example below has exactly the same effect as the one above:

	 use Class::MethodMaker
	   [ scalar => [ qw/ -static bar /],
	     scalar => 'foo',
	   ];

       Arrayrefs may be employed within a set of arguments for a single data-
       structure to likewise limit scope.  The example below has exactly the
       same effect as the one above:

	 use Class::MethodMaker
	   [ scalar => [ [ qw/ -static bar / ], 'foo' ],
	   ];

   Method Renaming
       Methods may be renamed, by providing options that map from one generic
       name to another.	 These are identified by the presence of a '*' in the
       option name.

       The example below installs component "a" as a scalar, but the method
       that would normally be installed as "a_get" is instead installed as
       "get_a", and likewise "set_a" is installed in place of "a_set".

	 use Class::MethodMaker
	   [ scalar => [ { '*_get' => 'get_*',
			   '*_set' => 'set_*', },
			 'a' ],
	   ];

   Default & Optional Methods
       Class::MethodMaker installs a number of methods by default.  Some
       methods, considered to be useful only to a subset of developers are
       installed only on request.  Each method is marked in the text to state
       whether it is installed by default or only upon request.

       To request that a non-default method is installed, one needs to rename
       it (even possibly to its normal name).  So, to install the *_get method
       for a scalar attribute (as *_get), the syntax is:

	 package MyClass;
	 use Class::MethodMaker
	   [ scalar => [{'*_get' => '*_get'}, 'a'] ];

       The method may be installed using a non-default name using similar
       syntax:

	 package MyClass;
	 use Class::MethodMaker
	   [ scalar => [{'*_get' => 'get_*'}, 'a'] ];

       The client may choose to not install a default method by renaming it to
       undef:

	 use Class::MethodMaker
	   [ scalar => [{'*' => undef }, 'a'] ];

       Note Class::MethodMaker will not install a method in place of an
       existing method, so if the intent is to not install a default method
       because the client has their own version, an alternative to the above
       is to define the client version before calling Class::MethodMaker.

   Naming & Method-Design Conventions
       The standard method names are designed with predictability and class
       extendibility in mind.

       Naming

       For any component x that Class::MethodMaker creates, the method names
       are always "x" or "x_*".	 This enables predictability, for you do not
       need to remember which methods are named "x_*" and which *_x, and also
       you can name methods that you create by avoiding prefixing them with
       "x", and so avoid any clash with Class::MethodMaker-generated methods
       (even if Class::MethodMaker is upgraded with shiny new extra methods).
       Class::MethodMaker users may rename methods (see "Method Renaming").

       For any data-structure component (scalar, array, hash, etc.) x that
       Class::MethodMaker creates, the method "x" sets the value of that
       component: i.e., overriding any existing value, not amending or
       modifying.  E.g., for array components, "x" does not push or pull
       values but all old values are removed, and new ones placed in their
       stead:

	 package MyClass;
	 use Class::MethodMaker
	   [ array => 'a',
	     new   => 'new',
	   ];

	 package main;
	 my $m = MyClass->new;
	 $m->a(4,5);
	 print join(' ', $m->a), "\n"; # 4 5
	 $m->a(6,7);
	 print join(' ', $m->a), "\n"; # 6 7

       The method returns the new value of the component:

	 print join(' ', $m->a(8,9)), "\n"; # 8 9

       Note that calling the method with an empty list does not reset the
       value to empty; this is so that normal lookups work on the method
       (i.e., if

	 $m->a

       emptied the component, then

	 @a = $m->a

       would always give an empty list: not that useful.

       Set/Unset

       Each data-structure component has the concept of being set/unset as a
       whole, independent of individual members being set.  Each component
       starts life unset (unless a default or default option or tie class has
       been supplied), and is becomes set by any assignment.  The component is
       then reset with the *_reset method.  Thus it is possible to distinguish
       between a component that has been set to an explicitly empty value, and
       one that has not been set (or been reset).  This distinction is
       analogous to the distinction in hashes between a missing key and a key
       whose value is undef.

	 package MyClass;
	 use Class::MethodMaker
	   [ new    => 'new',
	     scalar => 'x',
	   ];

	 package main;
	 my $m = MyClass->new;

	 $\ = "\n";
	 print $m->x_isset ? "true" : "false";	  # false; components start this way

	 my $x = $m->x;
	 print defined $n ? "->$n<-" : '*undef*'; # *undef*
	 print $m->x_isset ? "true" : "false";	  # false; reading doesn't set

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

	 $m->x("foo");
	 $x = $m->x;
	 print $m->x_isset ? "true" : "false";	  # true; undef is valid value
	 print defined $n ? "->$n<-" : '*undef*'; # *undef*

	 $m->x_reset;
	 $x = $m->x;
	 print defined $n ? "->$n<-" : '*undef*'; # *undef*
	 print $m->x_isset ? "true" : "false";	  # false

       It is not an error to query the value of an unset component: the value
       is undef.  Querying (any passive command, or pure function) an unset
       component does not cause it to become set; only assigning (any active
       command, or procedure) changes the set status of a component.

       NOTE THAT lvalues are still experimental (as of perl 5.8.0), and so
       their implementation may change r disappear in the future.  Note that
       lvalue use defeats type-checking.  This may be considered a bug, and so
       may be fixed if possible at some point in the future.

       Other Design Considerations

       Further design goals for Class::MethodMaker version 2:

       Consistency of Options
	   The options passed to components are now handled in a single place,
	   to try to be phrased consistently.  As many options as possible are
	   common to all data-structures.

       Flexibility
	   It is intended that all common class-construction options are
	   supported across all data-types, so that e.g., defaults, ties,
	   typing may be used with your data-structure of choice, and
	   combined.

       Speed
	   The methods are intended to be as fast as possible, within other
	   constraints outlined here.

   Options to "use"/"import"
       "-target_class"
	   By default, the target class is determined to be the last (latest)
	   class in the call stack that is not a Class::MethodMaker::Engine
	   subtype.  This is what is wanted 99% of the time, and typical users
	   need not worry.  However, the target class may be set explicitly in
	   the call to "use"/"import":

	     use Class::MethodMaker
	       [ -target_class => 'X',
		 scalar	       => [qw/ a /],
		 -target_class => 'Y',
		 scalar	       => [qw/ b /],
	       ];

	   Note that the "-target_class" option is order sensitive: it affects
	   only components requested after it in the call to "use"/"import".
	   As shown, the same call may handle specify multiple target classes.
	   Any components requested before the first "-target_class" are
	   created in the default-determined class, as outlined above.

	   Setting the target class in this way does not persist over multiple
	   calls to "use"/"import".  A subsequent call to either will use the
	   default-determined class as target (unless again overriden by
	   "-target_class").

   Standard Options for Data-Structure Components.
       The following options are observed by all data structure components
       (scalar, array, hash).

       -static
	     package MyClass;
	     use Class::MethodMaker
	       [ scalar => [qw/ -static s /], ];

	   This option causes components to hold class-specific, rather than
	   instance-specific values.  Thus:

	     package main;
	     my $m = MyClass->new;
	     my $n = MyClass->new;
	     $m->a(4,5);
	     print join(' ', $m->a), "\n"; # 4 5
	     print join(' ', $n->a), "\n"; # 4 5
	     $n->a(6,7);
	     print join(' ', $n->a), "\n"; # 6 7
	     print join(' ', $m->a), "\n"; # 6 7

       -type
	     use Class::MethodMaker
	       [ scalar => [{ -type => 'File::stat' }, 'st' ]];

	   Takes the name of a class, and checks that all values assigned to
	   the component are of the appropriate type (uses UNIVERSAL::isa, so
	   subtypes are permissible).

       -forward
	   This option takes as value an arrayref (or a simple scalar).	 The
	   values specify a list of methods that when called on an instance of
	   the target class, are "forwarded on" to the given component.	 For
	   example,

	     package X;

	     use Class::MethodMaker
	       [scalar => [{ -type => 'File::stat',
			     -forward => [qw/ mode size /], },
			   'st1',
			  ],
	       ])},

	   any call of "mode" or "size" on an instance of "X" wil simply call
	   the method of the same name on the value stored in the component
	   "st1", with the same arguments, and returns the value(s) of this
	   call.

	   Forwarding only applies to the first named component (since the
	   methodname is fixed, without the a componentname part).  This is
	   because the components are installed in the order in which they are
	   created, and Class::MethodMaker never overwrites a pre-existing
	   method.  So, in the following example, "mode" and "size" forward to
	   the "st1" component, and "read" forwards to the "st2" component.

	     package MyClass;
	     Class::MethodMaker->import([scalar =>
					   [{ -type    => 'File::stat',
					      -forward => [qw/ mode
							       size /],
					    },
					    qw( st1 ),
					    { -type    => 'IO::Handle',
					      -forward => 'read', },
					    qw( st2 ),
					   ]])},

	   Forwarding a method to a component of composite data type (e.g.,
	   array, hash) causes the method to be mapped over the values of that
	   component.  The returned value is appropriate to the component
	   type; so a method forwarded to an array will return a list, like
	   the array that is the component, but with each value being the
	   instead result of applying the forwarded method to the
	   corresponding value of the array.

	   The following code populates the @sizes array with the sizes of
	   /etc/passwd, /etc/group, in that order.

	     package main;
	     my $m = MyClass->new;
	     $m->st1("/etc/passwd", "/etc/group");
	     my @sizes = $m->size;

	   Calling the forwarding method in a scalar context will get the same
	   results, but as an arrayref:

	     my $sizes = $m->size; # [ 921, 598 ] for example

	   Likewise, forwarding to a hash component will return a hash from
	   original key to result of method on the corresponding component, or
	   an equivalent hashref in scalar context.

       -default
	     use Class::MethodMaker
	       [ scalar => [{ -default => 7 }, 'df1' ]];

	   Takes a simple value; must be either undef or an instance of the
	   appropriate type if "-type" has also been specified.	 Whenever a
	   component is new or reset, its value(s) default to the value given.
	   Hence *_isset will always return true for that component.  For
	   compound data-structures, the default applies to the each element
	   of the structure, not the compound itself.  So, for array
	   structures, the default applies to each element of the array, not
	   the array itself.

	   It is an error to specify the "-default" option and the
	   "-default_ctor" option simultaneously.

       -default_ctor
	     use Class::MethodMaker
	       [scalar => [{ -default_ctor => sub {
			       Y->new(-3);
			     },
			   'df2',

			   { -type	   => 'Y',
			     -default_ctor => 'new' },
			   'df3',
			  ]
	       ];

	   Takes a coderef to call to generate the default value.  This is
	   called the first time a value is required, and afterwards whenever
	   reset is called.  The subr is called with one argument, which is
	   the object upon which the component exists (or the name of the
	   class upon which the component is created, if the call is made on
	   the class).

	   If the "-type" option is in effect, then the value may be a simple
	   value, which shall be considered the name of a method to call on
	   the class specified by "-type".

	   It is an error to specify the "-default" option and the
	   "-default_ctor" option simultaneously.

       -tie_class
	     # @z is an audit trail
	     my @z;
	     package W;
	     use Tie::Scalar;
	     use base qw( Tie::StdScalar );
	     sub TIESCALAR { push @z, [ 'TIESCALAR'	]; $_[0]->SUPER::TIESCALAR    }
	     sub FETCH	   { push @z, [ 'FETCH'		]; $_[0]->SUPER::FETCH	      }
	     sub STORE	   { push @z, [ STORE => $_[1]	]; $_[0]->SUPER::STORE($_[1]) }
	     sub DESTROY   { push @z, [ 'DESTROY'	]; $_[0]->SUPER::DESTROY      }
	     sub UNTIE	   { push @z, [ UNTIE => $_[1]	]; $_[0]->SUPER::UNTIE($_[1]) }

	     package X;
	     Class::MethodMaker->import([scalar =>
					   [{ -type	 => 'File::stat',
					      -tie_class => 'W',
					      -forward	 => [qw/ mode
								 size /],
					    },
					    qw( tie1 ),
					 new => 'new',
					]]);

	   This option takes a simple value as argument, which is taken be the
	   name of a class that is to be tied to the storage for the
	   component, e.g., for an array component, a class that implements
	   the API for tied arrays is needed (see Tie::Array for more
	   information on this).  Likewise for scalar components, hash
	   components, etc.  Note that it is the component that is tied, not
	   the data items.

	     package main;
	     my $x = X->new;

	     # @z is empty

	     my $stat1 = stat "/etc/passwd";
	     my $stat2 = stat "/etc/group";
	     $x->tie1($stat1);

	     # @z is (['TIESCALAR'], ['STORE', $stat1])

	     my $y = $x->tie1;

	     # $y is $stat1
	     # @z is (['TIESCALAR'], ['STORE', $stat1], ['FETCH'])

	     $x->tie1($stat2);

	     # @z is (['TIESCALAR'], ['STORE', $stat1], ['FETCH'], ['STORE', $stat2])

	     $x->tie1_reset;

	     # @z is (['TIESCALAR'], ['STORE', $stat1], ['FETCH'], ['STORE', $stat2],\
	     #	      ['DESTROY'])

       -tie_args
	     package X;
	     Class::MethodMaker->import
	       ([scalar => [{ -tie_class => 'V',
			      -tie_args	 => [enum    => [qw/A B C/],
					     default => 'B'],
			    },
			    qw( tie2 ),
			   ]]);

	   This option takes an array reference, whose members are passed as
	   arguments to any tie invoked on the component (by virtue
	   "-tie_class").  If "-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...

       -read_cb
	   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

       -store_cb
	   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.

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.

SEE ALSO
       Class::MethodMaker::Engine, Class::MethodMaker::scalar,
       Class::MethodMaker::array, Class::MethodMaker::hash,
       Class::MethodMaker::V1Compat

perl v5.10.1			  2010-05-10		 Class::MethodMaker(3)
[top]

List of man pages available for Scientific

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Tweet
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
....................................................................
Vote for polarhome
Free Shell Accounts :: the biggest list on the net