OOP with Moo
There are several ways to write Object Oriented Perl. You can manually bless references, you can use one of the constructor and accessor generator modules, or you can use one of the modules from the Moose family. Moo is the Minimalist Object Orientation with Moose compatibility. In this screencast you'll learn the basics. (3:19 min)
#!/usr/bin/perl use strict; use warnings; use 5.010; use Person;
The other one is the actual Person module in the Person.pm file that has at the beginning the namespace declaration package Person; and the true value 1; at the end.
package Person; 1;
It does not have use strict; and use warnings; because we are going to use Moo;. and use Moo already declares that use strict; and use warnings; are in effect in this file.
The main thing that Moo does here, is that it provides a constructor:
package Person; use Moo; 1;
Now we can go back to the script and create an object. Let's say this is a student
and it gets the result of the constructor:
Now we have this $student object, but it does not have any attributes.
Let's go back to the class and tell it that a person has a name, and that name
is going to be read only. has name => (is => 'ro');
Once we added this line of code:
we can go back to our script and in the constructor we can pass the
name attribute and a value 'Foo'.
my $student = Person->new(name => 'Foo');
Not only that, but we can also use the name accessor to fetch this value
and print it out using say: say $student->name;.
That's it. Now we can go to the command line and run the school script
perl school.pl and it will print out Foo, the name of the
person.
What happens if we want to change the name? We try to set the value of
name to 'Bar': $student->name('Bar'); and then, just so
we will see it, we will print it out again: say $student->name;.
Now if we run the code perl school.pl it will print out Foo,
but then it will throw an exception.
Moo threw an exception and it told us that this method only accepts one value
which is the self. We don't want to go into the details, but basically
when you call a method such as the $student->name('Bar'); method on an object,
Perl automatically passes the object as the first parameter. So in this call we had
two parameters: the object itself and the 'Bar' value. That's where the error message
came from.
In reality, the exception is because in the declaration, in the Person module, we said
that this attribute is read-only: ro. If we change that to be both readable
and writable rw like this: has name => (is => 'rw');, save the file,
go back to the console and run the script again: perl school.pl it will print out:
because now we can actually change that attribute.
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
use Person;
my $student = Person->new;
package Person;
use Moo;
has name => (is => 'ro');
1;
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
use Person;
my $student = Person->new(name => 'Foo');
say $student->name;
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
use Person;
my $student = Person->new(name => 'Foo');
say $student->name;
$student->name('Bar');
say $student->name;
Foo
Usage: Person::name(self) at school.pl line 9.
Foo
Bar