LoginSignup
6
5

More than 5 years have passed since last update.

Perlでメソッドをoverloadする方法

Posted at

Perlではメソッドのオーバーロードが出来ない様ですね。まぁこんなだけ変数の型にゆるゆるだったら、出来るわけもないのかと思ったりもしますが、、、

代替策としてこんなのがあるみたい。
私としては、まとまってていいなーって感じです。

Triangle.pm
package Triangle;
use Carp qw(croak);

my $subSpace = sub {
        my($a,$b,$c) = @_;
        my $s = ($a + $b + $c) / 2;
        my $inRoot = $s * ($s - $a) * ($s - $b) * ($s - $c);
        if ($inRoot >= 0){
                return sqrt($inRoot);
        }else{
                croak "you cannot construct the triangle with the sides $a, $b, $c !";
        }
};
sub new{
        my ($class,$a,$b,$c) = @_;
        bless{a=>$a, b=>$b,c=>$c, s=>$subSpace->($a,$b,$c)};
#       my $self = {a=>$a, b=>$b, c=>$c};
#       bless $self, $class;
#       return $self;
}

sub space{
        my ($self) = shift;
        warn "You are about to calculate the space of ", ref($self), "!!!\n";
        return $self->{s};
}


sub getSides{
       my $self = shift;
       return ($self->{a}, $self->{b}, $self->{c});
}

sub setSides{
       my ($self, $a, $b, $c) = @_;
       $self->{a} = $a;
       $self->{b} = $b;
       $self->{c} = $c;
       $self->{s} = $subSpace->($a,$b,$c);
}

1;

このgetter setterの部分を、同じメソッド名にして、それぞれ引数の数に応じて呼ぶモジュールを変えます。

Triangle.pm~その2~
sub sides{
        my $self = shift; # invocant
        unless (@_) { # getter
                return ($self->{a}, $self->{b}, $self->{c}); # return properties
        } else { # setter
                my ($a, $b, $c) = @_;
                # get values from arguemnts and set properties
                $self->{a} = $a;
                $self->{b} = $b;
                $self->{c} = $c;
                $self->{s} = $subSpace->($a,$b,$c);
        }
}

モジュールはこんなもんで、あとはコレを呼ぶ側で、呼ぶメソッドをsetSides, getSidesからそれぞれsidesに統一したら完了です。

呼ぶ側のコードの例はこんな感じです。

triangleSpace.pl
#! /bin/perl -w

use Triangle;

my $tri = Triangle->new(3,4,5);
my $space = $tri->space;
print "sides are ", join(",",$tri->sides), ". \n";
print "Triangle is ",$tri," and its space is ",$space,"\n";

my ($a,$b,$c) = $tri->sides;
$tri->sides($a,$b,$c);
$space = $tri->space;
print "sides are ",join(", ",$tri->sides), ". \n";
print "Triangle is ",$tri," and its space is ",$space,"\n";

同じ結果になっていることを確認して頂けたでしょうか?

めんどいんだかなんだかわかりませんが、こんなやり方も出来るんですね~ 勉強になりました。

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5