NAME
Class::Constructor - Simplify the creation of object constructors
SYNOPSIS
package MyPackage;
# Note if you don't have the CLASS package installed,
# you can use the __PACKAGE__ keyword instead
use CLASS;
use base qw/ Class::Constructor Class::Accessor /;
my @Accessors = qw(
some_attribute
another_attribute
yet_another_attribute
);
CLASS->mk_accessors(@Accessors);
CLASS->mk_constructor(
Name => 'new',
Auto_Init => \@Accessors,
);
DESCRIPTION
Simplifies the creation of object constructors.
Instead of writing:
sub new {
my $proto = shift;
my $class = ref $proto || $proto;
my $self = {};
bless $self, $class;
my %args = @_;
foreach my $attr ('first_attribute', 'second_attribute') {
$self->$attr($args{$attr});
}
$self->_init();
return $self;
}
You can just write:
CLASS->mk_constructor(
Auto_Init => [ 'first_attribute', 'second_attribute' ],
);
There are other features as well:
- Automatically call other initialization methods.
-
Using the
Init_Methods
method ofmk_constructor
, you can have your constructor method automatically call one or more initialization methods. - Automatic Construction of objects of Subclasses
-
Your constructor can bless objects into one of its subclasses.
For instance, the
Fruit
class could bless objects into theFruit::Apple
orFruit::Orange
classes depending on a parameter passed to the constructor.See Subclass_Param for details.
METHOD
mk_constructor
CLASS->mk_constructor(
Name => 'new',
Init_Methods => [ '_init' ],
Subclass_Param => 'Package_Type',
Auto_Init => [ 'first_attribute', 'second_attribute' ],
);
The mk_constructor
method creates a constructor named Name
in CLASS
's namespace.
- Name
-
The name of the constructor method. The default is
new
. - Init_Methods
-
Cause the created constructor to call the listed methods on all new objects that are created via the constructor.
Foo->mk_constructor( Name => 'new', Init_Methods => '_init', ); my $object = Foo->new; # This calls $object->_init(); Foo->mk_constructor( Name => 'new', Init_Methods => [ '_init', '_startup' ], ); my $object = Foo->new; # after construction, new() # calls $object->_init(), # then $object->_startup()
- Auto_Init
-
A list of attributes that should be automatically initialized via the parameters to the constructor.
For each name/value pair passed to the constructor, the constructor will call the method named
name
with the parameter ofvalue
.For instance, if you make your constructor with:
Fruit->mk_constructor( Auto_Init => [ 'size', 'colour' ], );
And you call the constructor with:
use Fruit; my $fruit = Fruit->new( size => 'big', colour => 'red', );
Then, internally, the
new
constructor will automatically call the following methods:$fruit->size('big'); $fruit->colour('red');
Note that by default,
Class::Constructor
converts names to lower case. SeeCASE SENSITIVITY
, below. - Required_Params
-
A list of params that must be passed to the constructor when the object is created. If these items are not already listed as
Auto_Init
methods, they will be added to theAuto_Init
list.Fruit->mk_constructor( Required_Params => [ 'size', 'price' ], ); package main; use Fruit; my $fruit = Fruit->new; # error, missing size, price my $fruit = Fruit->new( # error: missing price size => 'big' ); my $fruit = Fruit->new( # okay size => 'big', price => 0.25, );
- Disable_Case_Mangling
-
Set this to a true value if you don't want Class::Constructor to force attribute names to lower case. See
CASE SENSITIVITY
, below. - Disable_Name_Normalizing
-
Another name for
Disable_Case_Mangling
, above. - Method_Name_Normalizer
-
Custom subroutine for converting a parameter passed to auto_init into a attribute name. See
CASE SENSITIVITY
, below. - Class_Name_Normalizer
-
Custom subroutine for converting a subtype class into a Perl class name. See
CASE SENSITIVITY
, below. - Param_Name_Normalizer
-
Custom subroutine to be applied to params passed to the constructor in order to recognize special ones, such as those that are required by
Required_Params
and the specialSubclass_Param
. SeeCASE SENSITIVITY
, below. - Subclass_Param
-
You can cause the constructor to make instances of a subclass, based on the a special parameter passed to the constructor:
# Fruit.pm: package Fruit; Fruit->mk_constructor( Name => 'new', Subclass_Param => 'Type', ); sub has_core { 0 }; # Fruit/Apple.pm: package Fruit::Apple; use base 'Fruit'; sub has_core { 1 }; # main program: package main; my $apple = Fruit->new( Type => 'Apple', ); if ($apple->has_core) { print "apples have cores!\n"; }
- Dont_Load_Subclasses_Param
-
The name of the parameter that will be checked by the constructor to determine whether or not subclasses specified by
Subclass_Param
will be loaded or not. This is mainly useful if you are writing test scripts and you want to load in your packages manually.For instance:
# Fruit.pm: package Fruit; Fruit->mk_constructor( Name => 'new', Subclass_Param => 'type', Dont_Load_Subclass_Param => 'Dont_Load_Subclass', ); # main program: package main; my $apple = Fruit->new( Type => 'Apple', Dont_Load_Subclass => 1, );
Now when the
$apple
object is created, the constructor makes no attempt to require theFruit::Apple
module.
CASE SENSITIVITY
By default, attribute names are forced to lower case and the case of Auto_Init
parameter names passed to the constructor doesn't matter.
So the following call to a constructor:
my $fruit = Fruit->new(
SiZE => 'big',
colOUR => 'red',
);
Is actually equivalent to:
my $fruit = Fruit->new();
$fruit->size('big');
$fruit->colour('red');
You can disable this behaviour by setting Disable_Case_Mangling
to a true value:
package Fruit;
Fruit->mk_constructor(
Disable_Case_Mangling => 1,
);
Now the parameters are left unchanged:
my $fruit = Fruit->new(
SiZE => 'big',
colOUR => 'red',
);
# equivalent to:
my $fruit = Fruit->new();
$fruit->SiZE('big');
$fruit->colOUR('red');
Similarly for class names as passed via Subclass_Param
, they are converted to lower case and then the first letter is uppercased.
# the following creates a Fruit::Apple
my $apple = Fruit->new(
Type => 'APPLE',
);
This behaviour is also disabled via Disable_Case_Mangling
:
package Fruit;
Fruit->mk_constructor(
Subclass_Param => 'Type',
Disable_Case_Mangling => 1,
);
# the following creates a Fruit::APPLE
my $apple = Fruit->new(
Type => 'APPLE',
);
Advanced: Customizing Class, Method and Param normalization.
Note that this is an advanced feature with limited use, so you can probably skip it.
If you want to customize the way Class::Constructor
changes method names, you can pass subroutines to do the work:
package Fruit;
Fruit->mk_constructor(
Subclass_Param => 'Type',
Method_Name_Normalizer => sub { '_' . lc $_[0] }, # precede lc methods with underscore
Param_Name_Normalizer => sub { uc $_[0] }, # params compared as upper case
Class_Name_Normalizer => sub { uc $_[0] }, # class names to uppercase
Required_Params => [ 'Size' ],
);
# the following creates a Fruit::APPLE
my $apple = Fruit->new(
Type => 'apple',
SiZE => 'big',
colOUR => 'red',
);
# and the above is equivalent to:
my $apple = Fruit->new(
type => 'apple',
);
$apple->_SiZE('big');
$apple->_colOUR('red');
In the example above, the Method_Name_Normalizer
causes auto_init to make convert parameter names into method names as follows:
SiZE => _size
colOUR => _colour
The Class_Name_Normalizer
converts the value of Type
(the Subclass_Param
) into method names as follows:
apple => APPLE
The Param_Name_Normalizer
converts param names to upper case before comparing them. So Subclass_Param
is specified to be Type
, and is eventually passed as type
. But since both are normalized to TYPE
, the match is found.
AUTHOR
Michael Graham <mag-perl@occamstoothbrush.com>
Copyright (C) 2001 Michael Graham. All rights reserved. This program is free software. You can use, modify, and distribute it under the same terms as Perl itself.
The latest version of this module can be found on http://www.occamstoothbrush.com/perl/