I am new to Perl, and I would like to understand/know more about the OO parts. Say I have a "class" with only attributes; are there benefits/advantages for creating a package and blessing a hash over working on a hash directly?
for simplicity, lets consider the following example :
package Person;
sub new {
my $class = shift;
my $args = {Name => '', Age => 0, @_};
my $self = { Name => $args->{Name},
Age => $args->{Age}, };
bless $self, $class;
}
package main;
my $person1 = Person->new(Name => 'David', Age => 20);
my $person2 = {Name => 'David', Age => 20, Pet => 'Dog'};
print $person1->{Name} . "\n";
print $person2->{Name} . "\n";
What I would like to know is what is the difference between $person1
and $person2
, beside the OO parts, beside the fact that 1 is a blessed hash and 2 is a hash reference?
Are there any benefits of working with an object, in this case, over working on a hash?
After reviewing the answers :
Thanks for all the help :)
Håkon Hægland comment has the closest answer for me, I was just wondering, consider I only have to hold, simple scalars, no special checks, no other functionality, are there benefits for a class over a simple hash (I understand that if I need extra functionality and inheritance a class will be the right tool)
If you are not going to use method calls, there is not so big difference. One thing you can do with $person1
is introspect the name of the class it was blessed into by calling ref $person1
. You could also arrange for Person
to inherit attributes from a base class.
Another thing you could do with Person
is to provide access validation to its data attributes. So instead of $person1->{Name}
you would implement a method name()
that returns $person1->{Name}
and perhaps does some other useful things like logging, or checking if the name is defined and so on.
For example:
#! /usr/bin/env perl
package LivingBeing;
use strict;
use warnings;
sub new {
die "LivingBeing: Wrong number of arguments to the constructor!" if @_ != 2;
my ( $class, $type ) = @_;
return bless {type => $type}, $class;
}
package Person;
use strict;
use warnings;
use parent -norequire => qw(LivingBeing);
sub new {
my ($class, %args) = @_;
my $self = $class->SUPER::new('human');
$self->{age} = 0; # Default value
$self->{$_} = $args{$_} for keys %args; # Maybe override default values..
return $self;
}
sub name {
my $self = shift;
my $name = $self->{name};
warn "Undefined name attribute" if !defined $name;
return $name;
}
package main;
use strict;
use warnings;
use feature qw(say);
my $person1 = Person->new(pet => 'cat', age => 20);
my $person2 = {name => 'David', age => 20, pet => 'dog'};
say "person1 is a : ", ref $person1;
say "person2 is a : ", ref $person2;
say "The name of person1 is: ", $person1->name;
say "The age of person1 is: ", $person1->{age};
Output:
person1 is a : Person
person2 is a : HASH
Undefined name attribute at ./p2.pl line 28.
Use of uninitialized value in say at ./p2.pl line 43.
The name of person1 is:
The age of person1 is: 20