NickNiu
NickNiu

Reputation: 41

How can a perl constructor return a value not just a hashref

I want to create a Perl OO module to return a value like DateTime does, but don't know how to it right now. Anyone's help on this will be appreciated.

Below looks like what I wanted:

use DateTime;
use Data::Printer;
my $time = DateTime->now();
print $time . "\n";
print ref $time;
# p $time; 

Output:

2022-11-23T13:22:39
DateTime

What I got:

package Com::Mfg::Address;
use strict;
use warnings;

#constructor
sub new {
    my ($class) = @_;
    my $self = { 
        _street       => shift || "undefined",
        _city => shift || "undefined",
        _las_state  => shift || "undefined",
        _zip   => shift || "undefined",
    };
    bless $self, $class;
    return $self;
}

#accessor method for street
sub street {
    my ( $self, $street ) = @_;
    $self->{_street} = $street if defined($street);
    return ( $self->{_street} );
}

#accessor method for city
sub city {
    my ( $self, $city ) = @_;
    $self->{_city} = $city if defined($city);
    return ( $self->{_city} );
}

#accessor method for state
sub state {
    my ( $self, $state ) = @_;
    $self->{_state} = $state if defined($state);
    return ( $self->{_state} );
}

#accessor method for zip
sub zip {
    my ( $self, $zip ) = @_;
    $self->{_zip} = $zip if defined($zip);
    return ( $self->{_zip} );
}

sub print {
    my ($self) = @_;
    printf( "Address:%s\n%s, %s %s\n\n",
        $self->street, $self->city, $self->state, $self->zip );
}

1;

# test.pl
#!/usr/bin/perl -w
use strict;
use Data::Printer;

BEGIN {
    use FindBin qw($Bin);
    use lib "$Bin/../lib";
}

use Com::Mfg::Address;
my $homeAddr = Com::Mfg::Address->new('#101 Road', 'LA', 'CA', '111111');
print $homeAddr;
# $homeAddr->print();
# p $homeAddr;

But this only gives me:

Com::Mfg::Address=HASH(0xb89ad0)

I am curious if print $homeAddr can give me:
something like #101Road-LA-CA-111111 and it really is object like above print $time . "\n";.

I tried to review DateTime source but still have no clue right now.

Upvotes: 1

Views: 71

Answers (1)

ikegami
ikegami

Reputation: 386331

You're asking how to provide a custom stringification for the object. Use the following in your module:

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

sub to_string {
   my $self = shift;
   return
      join ", ",
         $self->street,
         $self->city,
         $self->state,
         $self->zip;
}

This makes

print $homeAddr;

equivalent to

print $homeAddr->to_string();

Upvotes: 2

Related Questions