In the previous article we saw how to create a class using bless, but when we printed the instance object we got My::Date=HASH(0x7f807c13c700). This can be useful as it tells us we are dealing with a My::Date object, but on the other hand it could print something more interesting. For example it could print a nice representation of the attributes: Date(2013, 1, 27)

Stringification

means that we take an object and create a string format. It happens when the object is placed in string context. For example when it is printed.

Operator overloading

In order to change the behavior of the My::Date class when an object of that type is placed in string context, we need to "overload" the stringification operator. It can be done using the overload module.

This is what needs to be added to the Date.pm file in the previous example.

use overload 
    '""' => 'stringify';

sub stringify {
    my ($self) = @_;
    return sprintf 'Date(%s, %s, %s)', $self->year, $self->month, $self->day;
}

The stringify subroutine, that can actually have any name, implements the actual stringification. In some modules the author call it to_string or to_str, the actual name only matters because the method can also be used on its own. A user could write:

my $d = My::Date->new(year => 2013, month => 1, day => 27);
say $d->stringify;

This will print Date(2013, 1, 27).

The first two lines in the above code, loads the overload module and tells it that when the object is in string context, call the stringify method. When "use"-ing the overload module we pass a set of key-value pairs. In this case the key is "" (two double-quotes) and the value is the name of the method that implements it.

The more interesting usage of this is when we just simply print $d:

my $d = My::Date->new(year => 2013, month => 1, day => 27);
say $d;

In this case too, perl will call the stringify method of the My::Date class, and will print the value returned by that function.

Which name-space does the object belong to?

Now that we change what a single object returns, we seem to have lost the previous information. To which class does this object belong to?

No problem, the ref function can tell us this information:

say ref $d;

will print My::Date.

Alternatively, one can use the blessed function of Scalar::Util

use Scalar::Util qw(blessed);
say blessed $d;

The advantage of the blessed function is that it will return undef if the values is not blessed, while ref can return values such as HASH, ARRAY etc. So if there is a scalar variable that you want to know if it is blessed or not, it is simpler to write

if (defined blessed $var) {
}

that to compare the result of ref to all the known types of references.

Full example

package My::Date;
use strict;
use warnings;

sub new {
    my ($class, %args) = @_;
    return bless \%args, $class;
}

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

sub month {
    if (@_ == 2) {
        $_[0]->{month} = $_[1];
    }
    return $_[0]->{month};
}

sub day {
    return $_[0]->{day} = @_ == 2 ? $_[1] : $_[0]->{day};
}



use overload 
    '""' => \&stringify;


sub stringify {
    my ($self) = @_;
    return sprintf 'Date(%s, %s, %s)', $self->year, $self->month, $self->day;
}

1;

use strict;
use warnings;
use 5.010;

use FindBin;
use File::Spec;
use lib File::Spec->catdir($FindBin::Bin, '..', 'lib');
use My::Date;

my $d = My::Date->new(year => 2013, month => 1, day => 27);
say $d->stringify;
say $d;

say ref $d;

use Scalar::Util qw(blessed);
say blessed $d;