package PurgeImperial; use strict; use overload ( '+' => "add", q("") => "quote", "<=>" => "compare" ); sub new { my ( $class, $value ) = @_; my ( $number, $unit ) = split /\s+/, $value; return unless $unit =~ /^(in|m)$/; if ( $unit eq "in" ){ $number *= 0.0254; $unit = "m" } return bless { number => $number, unit => $unit }, $class; } sub add { my ( $object1, $object2, $was_reversed ) = @_; my $class = ref $object1; $object2 = $class->new( $object2 ) unless UNIVERSAL::isa( $object2, $class ); ( $object1, $object2 ) = ( $object2, $object1 ) if $was_reversed; # see explanation below my $sum = $object1->{number} + $object2->{number}; return $class->new( "$sum m" ); } sub quote { my ( $object ) = @_; return join " ", $object->{number}, $object->{unit}; } sub compare { my ( $object1, $object2, $was_reversed ) = @_; ( $object1, $object2 ) = ( $object2, $object1 ) if $was_reversed; return $object1->{number} <=> $object2->{number}; } my %handlers = ( q => sub { print "doing $_[0]"; return __PACKAGE__->new( $_[0] ) || $_[1]; } ); sub import { overload::constant( %handlers ) if $_[ 1 ] eq ':constants'; } sub unimport { overload::remove_constant( q => undef ); }