In the case of Moose after we have seen that in the regular script, we could set the value of an attribute using a 'setter', and we could get the value of an attribute using a 'getter'.

Download: mp4 ogv webm

examples/Moose/person01/script/person.pl

use strict;
use warnings;
use v5.10;

use Person;

my $teacher = Person->new;

$teacher->name('Foo');

say $teacher->name;

We implemented that in the Person.pm module:

examples/Moose/person01/lib/Person.pm

package Person;
use Moose;

has 'name' => (is => 'rw');

1;

The we also saw that we can set the initial value of the attribute in the constructor already:

examples/Moose/person01/script/person2.pl

use strict;
use warnings;
use v5.10;

use Person;

my $teacher = Person->new( name => 'Foo' );

say $teacher->name;

We can pass key-value pairs in the constructor and the same minimalistic code in Moose already provides us this feature.

Constructor arguments in core Perl OOP

This is not the same with core Perl OOP. Here we had to implement the getter/setter by ourselves and we also have to implement the accepting of parameters in the constructor.

In order to have this in core Perl OOP we created a method to be the getter/setter, but in order to be able to accept key-value pairs by the constructor we have to make some further changes.

Earlier, in the original constructor we only accepted the name of the class and nothing else and we used an empty hash reference as $self:

examples/oop/person00/lib/Person.pm

package Person;
use strict;
use warnings;

sub new {
    my ($class) = @_;

    my $self = {};

    bless $self, $class;

    return $self;
}


1;

This was changed so the new function, the constructor is now also accepting a set of key-value pairs and assigns them to the %args and then uses the reference to that hash as the base of that object.

examples/oop/person01/lib/Person.pm

package Person;
use strict;
use warnings;

sub new {
    my ($class, %args) = @_;

    my $self = \%args;

    bless $self, $class;

    return $self;
}

sub name {
    my ($self, $value) = @_;
    if (@_ == 2) {
        $self->{name} = $value;
    }

    return $self->{name};
}

1;

This provides us the feature that users can pass key-value pairs and they will be used as attributes in the object being created.

As you might have noticed there is no checking here if the keys the user has passed in the constructor are the really the field-names we are expecting. Nor is there any constraints on the values passed to the constructor.