A couple of times I met the original options for creating objects in your favorite Perl and sighs about 6-ki, that everything is easier, better, faster, etc. However, quite nice and
completely safe constructions can be fenced in the “folk” five. We use the classic version of the textbook with closures and a pile of pepper :)
So, in order not to delay and not embarrass the guru - I quote the code right away, the explanations will be under it:
package Person;
use Carp;
use strict;
my ($init,$setup);
sub new {
my $invocant = shift;
my $self = bless({}, ref $invocant || $invocant);
$self- > $init();
$self- > $setup(@_);
return $self;
}
$init = sub {
my $self = shift;
$self- > name("unnamed"); # end etc
};
for my $field (qw(name race aliases)) {
my $slot = __PACKAGE__ . "::$field";
no strict "refs"; # So symbolic ref to typeglob works.
*$field = sub {
my $self = shift;
$self- > {$slot} = shift if @_;
return $self- > {$slot};
};
}
$setup = sub {
my $self = shift;
my %var = @_;
no strict "refs";
foreach (keys %var) {
if (*$_{CODE}) {$self- > $_($var{$_});}
else {carp (qq{Haven`t properties "$_" in object }.__PACKAGE__." ");}
}
};
* This source code was highlighted with Source Code Highlighter .
')
We get a great package for creating objects by a completely classic method:
my $mage = Person- > new(name= > "Gandalf",race= > "Istar");
"- What kind of nafik reprint textbook?" - you ask.
Well, in fact, there are a couple of differences from the textbook -
- we calmly transfer the parameters of the new object to the constructor right away
- we calmly allow the constructor to pass parameters with an error - the object will still be created (with all valid properties), and the user (of the module) will receive a message that he tried to set an unknown property. Perhaps this will lead him to read the module documentation.
And the whole construction is obtained openwork and durable - an attempt to “screw” the property, which we have not provided for, will give a fatal error indicating the place in the user’s code (module) by Perl itself.
IMHO is much more "transparent" use of "large" module-wrappers OOP functions.
Ps. It is obvious that nothing prevents us from making some of the properties of RO - we add type checking to the closure:
if (__PACKAGE__ eq (caller)) {#inner call}
and cut off the write calls to the RO properties outside, leaving only the inner call (do we want to work with this property?).
UP . Based on this topic was born prefabricated
Botox - just copy and use wisely.