Advertisement
cwchen

Operator overloading demo in Perl

Feb 10th, 2016
197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 2.32 KB | None | 0 0
  1. package Number::Complex;
  2.  
  3. use Scalar::Util qw(looks_like_number);
  4. use Carp qw(croak);
  5. use Moo;
  6. use overload
  7.     '+' => \&plus,
  8.     '-' => \&minus,
  9.     '""' => \&to_string;
  10. use namespace::sweep;
  11.  
  12. has 'real' => (
  13.     is => 'ro',
  14.     isa => sub {
  15.         my $item = shift;
  16.         croak "$item is not a number" unless looks_like_number $item;
  17.     },
  18.     default => 0,
  19.     writer => '_set_real',
  20.     );
  21.  
  22. has 'imag' => (
  23.     is => 'ro',
  24.     isa => sub {
  25.         my $item = shift;
  26.         croak "$item is not a number" unless looks_like_number $item;
  27.     },
  28.     default => 0,
  29.     writer => '_set_imag',
  30.     );
  31.  
  32. around 'BUILDARGS' => sub {
  33.     my $orig = shift;
  34.     my $class = shift;
  35.  
  36.     if (@_ == 2) {
  37.         my ($real, $imag) = @_;
  38.         return $class->$orig(real => $real, imag => $imag);
  39.     }
  40.     else {
  41.         return $class->$orig(@_);
  42.     }
  43. };
  44.  
  45. sub plus {
  46.     my ($self, $other, $swap) = @_;
  47.     my $class = ref $self;
  48.     my $result = $class->new();
  49.     if (!$swap and ref $other) {
  50.         $result->_set_real($self->real() + $other->real());
  51.         $result->_set_imag($self->imag() + $other->imag());
  52.     }
  53.     else {
  54.         $result->_set_real($self->real() + $other);
  55.         $result->_set_imag($self->imag());
  56.     }
  57.     return $result;
  58. }
  59.  
  60. sub minus {
  61.     my ($self, $other, $swap) = @_;
  62.     my $class = ref $self;
  63.     my $result = $class->new();
  64.     if (!$swap and ref $other) {
  65.         $result->_set_real($self->real() - $other->real());
  66.         $result->_set_imag($self->imag() - $other->imag());
  67.     }
  68.     elsif (!$swap) {
  69.         $result->_set_real($self->real() - $other);
  70.         $result->_set_imag($self->imag());
  71.     }
  72.     else {
  73.         $result->_set_real($other - $self->real());
  74.         $result->_set_imag(-$self->imag());
  75.     }
  76.     return $result;
  77. }
  78.  
  79. sub to_string {
  80.     my $self = shift;
  81.     my $real_str = $self->real();
  82.     my $imag_str = $self->imag() >= 0
  83.         ? "+" . $self->imag() : $self->imag();
  84.     return sprintf "%s%si", $real_str, $imag_str;
  85. }
  86.  
  87. __PACKAGE__->meta->make_immutable;
  88.  
  89. unless (caller) {
  90.     package main;
  91.     use feature qw(say);
  92.  
  93.     my $a = Number::Complex->new(3, 4);
  94.     my $b = Number::Complex->new(4, 3);
  95.  
  96.     say $a + $b;
  97.     say $a + 2;
  98.     say 2 + $a;
  99.  
  100.     say $a - $b;
  101.     say $a - 2;
  102.     say 2 - $a;
  103. }
  104.  
  105. 1;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement