Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

To bless or not to bless, that is my question!

first post from a newbie-user. Every question I google seems to bring me here and I always get a great answer to what I'm looking for; so naturally this was my first stop when I began pondering the usage of blessing in Perl.

I've just gotten into Perl's OOP and just today read the post asking what bless does. I now understand that it references a scalar/hash/array to an object, 'attaching' it, if you will.

In most of the examples of classes I see in Perl, they don't seem to have properties like I'm used to seeing in other languages...

{ package Person;
    my $property = "This is what I'm talking about :)";

    sub new { ... }
    ...
}

So, I created a stupid class with a property to see what would happen. I gave the property the value 'NIL' right off the bat and then 'Not Nil!' in the constructor. Using a method LIST, I was able to print the property, and as I expected, it printed 'Not Nil!'

My question is, if properties work the same as I expected them to work (declared in the body) then why use bless at all? What is the added benefit of having that reference when you could simply create a scalar/hash/array as a property, or create whatever references you want as a property?

I hope I explained what I'm trying to ask well enough, very green with Perl :)

like image 714
NiRC Avatar asked Aug 11 '10 03:08

NiRC


1 Answers

Well, that is not how you create classes in Perl.

Your $property variable is defined in package scope. Therefore, there will only one copy of it per class rather than each object having its own copy.

One might implement such a class using hash based objects the long and hard way as below:

#!/usr/bin/perl

package Person;

use strict; use warnings;

sub new {
    my $class = shift;
    my $self = {};
    bless $self => $class;

    my ($arg) = @_;
    for my $property ( qw( message ) ) {
        if ( exists $arg->{$property} ) {
            $self->$property($arg->{$property});
        }
    }
    return $self;
}

sub message {
    my $self = shift;
    return $self->{message} unless @_;
    my ($msg) = @_;
    $self->{message} = $msg;
}

package main;

my $person = Person->new({
    message => "This is what I'm talking about :)"
});

print $person->message, "\n";

Now, this gets tedious fast. So, there are modules that help you deal with this as well as helping you define your classes in way that is safe for inheritance.

Class::Accessor is one such utility module.

For programs where startup time is not an issue, you should consider Moose. With Moose, you can write the above as:

#!/usr/bin/perl

package Person;

use Moose;

has 'message' => (is => 'rw', isa => 'Str');

__PACKAGE__->meta->make_immutable;
no Moose;

package main;

my $person = Person->new({
    message => "This is what I'm talking about :)"
});

print $person->message, "\n";

You should read perldoc perltoot and Moose::Manual::Unsweetened for the standard way of doing things.

like image 99
Sinan Ünür Avatar answered Nov 13 '22 01:11

Sinan Ünür