Translate

2013年8月17日土曜日

[perl]複数のコンストラクタに対応するには?

学習のため、某JavaのソースコードをPerlで表現してみる。

Javaでは引数違い同名のメソッドを持つことができます。
便利ですね。

class Rectangle {
    int width;
    int height;
    Rectangle(){
        setSize(10, 20);
    }
    Rectangle(int w, int h){
        setSize(w, h);
    }    
    void setSize(int w, int h){
        width = w;
        height = h;
    }
    int getArea(){
        return width * height;
    }
}

引数無しのnewならデフォルト10, 20をセット
値があればそちらをセット同じことをPerlでやってみます。
処理をまねするならこうなるでしょうかねぇ?
package Rectangle;                                                                 
use strict;
use warnings;
use utf8;
binmode STDERR, ":utf8";

sub new{
    my $self  = bless{}, shift;

    #引数チェック
    if(@_==0){
        $self->setSize(10, 20);
    }elsif(@_==2){
        $self->setSize($_[0], $_[1]);
    }else{                                                                         
        die("コンストラクタは引数無し または、                                     
            2引数を指定してください(width, height)");
    }

    return $self;                                                                  
}

sub setSize{
    my $self = shift;
    if(@_!=2){die("setSizeの引数を2つ指定してください(width, height)")}
    $self->{width}  = $_[0];
    $self->{height} = $_[1];
}

sub getArea{
    my $self = shift;
    return $self->{width} * $self->{height};
}

1;
引数を明示しない言語なので引数違いの同名メソッドは作れないので
引数の数で振り分けるしかないと思います。

実行してみます。
use strict;
use warnings;
use utf8;
use feature 'say';
binmode STDOUT, ":utf8";

use lib qw(lib);
use Rectangle;                                                                     

my $r1 = Rectangle->new();
my $r2 = Rectangle->new(123, 5);

output($r1);
output($r2);

sub output{
    my $self = shift;
    say "幅 :". $self->{width};
    say "高さ:". $self->{height};
    say "面積:". $self->getArea();
}

実行結果:
幅 :10
高さ:20
面積:200
幅 :123
高さ:5
面積:615

0 件のコメント: