Let’s play with overloading a bit.
A easy class:
package deal Native::Overloaded {
use Moo;
has quantity => ( is => 'ro' );
use overload '0+' => sub {
my $self = shift;
return $self->quantity;
};
}
And let’s take a look at it:
use Test2::V0;
my $obj = Native::Overloaded->new( quantity => 42 );
is( 0+$obj, 42 );
done_testing;
This take a look at fails.
Why?
We have a tendency to consider 0+
as the way in which to “forged” a Perl variable to a quantity, a lot in order that the overload pragma even calls the numeric overload “0+”. Nonetheless it’s in fact truly an addition, and we haven’t overloaded the plus operator.
The easy answer is to simply together with the fallback => true
possibility when overloading. This tells Perl to fill in as many lacking overloaded operations it will probably primarily based on the operations you’ve explicitly offered.
However I’m not within the easy answer. I’m fascinated with what we will do with the “0+” overload.
Let’s strive rephrasing our take a look at case:
use Test2::V0;
my $obj = Native::Overloaded->new( quantity => 42 );
okay( $obj == 42 );
done_testing;
This nonetheless fails. The equality operator isn’t overloaded both.
Nonetheless, this one works:
use Test2::V0;
my $obj = Native::Overloaded->new( quantity => 42 );
is( $obj, 42 );
done_testing;
So how is Test2 evaluating them?
The reply is that at any time when the correct hand aspect of an is
comparability is a non-reference, Test2 compares them as strings. Particularly, it does this:
"$left" eq "$proper"
And for no matter cause, although we didn’t set fallback => true
, Perl will fortunately apply the numeric overload when an object is interpolated right into a string and doesn’t have a string overload.
So let’s add some stringy overloading to our class:
package deal Native::Overloaded {
use Moo;
use Lingua::EN::Numbers qw( num2en );
has quantity => ( is => 'ro' );
use overload (
'0+' => sub {
my $self = shift;
return $self->quantity;
},
'""' => sub {
my $self = shift;
return num2en( $self->quantity );
},
);
}
Now our beforehand passing take a look at fails:
use Test2::V0;
my $obj = Native::Overloaded->new( quantity => 42 );
is( $obj, 42 );
done_testing;
It’s evaluating “forty-two” and “42” as strings.
So that is the place we come upon the protected method to forged to a quantity. And it’s nonetheless not 0+
.
use Test2::V0;
my $obj = Native::Overloaded->new( quantity => 42 );
is( sprintf( '%d', $obj ), 42 );
is( sprintf( '%s', $obj ), 'forty-two' );
done_testing;
Passing the item to sprintf( '%d' )
for integers or sprintf( '%f' )
will truly use the numeric overload with out complaining about ==
and +
not being overloaded. This appears probably the most dependable method to forged an object to a quantity if it doesn’t have overload fallbacks enabled, otherwise you’re undecided if it does.
The lesson right here is that overloading will be bizarre in Perl, however utilizing fallback => true
makes it so much much less bizarre.
The opposite lesson is to make use of sprintf( '%d' )
or sprintf( '%f' )
to forged to a quantity as a substitute of 0+
.