# # Triangle.pm -- 三角形クラス(オブジェクトを生成する) # (* のオーバーロード) # # sample file name: Triangle.pm.017 package Triangle; use Carp qw(croak); use overload '""' => "toString", '0+' => "toNumber", '+' => "add", '-' => "subtract", '*' => "multiply", ; 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) }; } sub space { my $self = shift; warn "You are about to calculate the space of ", ref($self), "!!! \n"; return $self->{s}; } sub sides { my $self = shift; # 値を 1 個、引数リストから取り除いて $self に入れる # これはインボカント unless (@_) { # もう引数リストに要素が残ってなければゲッター return ($self->{a}, $self->{b}, $self->{c}); # プロパティを返して終了 } else { # まだ要素が残ってればセッター my ($a, $b, $c) = @_; # 引数から値を取得してプロパティを再設定して終了 $self->{a} = $a; $self->{b} = $b; $self->{c} = $c; $self->{s} = $subSpace->($a, $b, $c); } } sub toString { my $self = shift; my $a = $self->{a}; my $b = $self->{b}; my $c = $self->{c}; return ("($a, $b, $c)"); } sub toNumber { my $self = shift; return ($self->{s}); } sub add { my ($self, $b) = @_; $a = sprintf "%g", $self; ref $b and $b = sprintf "%g", $b; return $a + $b; } sub subtract { my ($self, $b, $swap) = @_; $a = sprintf "%g", $self; ref $b and $b = sprintf "%g", $b; unless ($swap) { return $a - $b; } else { return $b - $a; } } sub multiply { my ($self, $x) = @_; (ref $x or $x =~ /[^\.0-9]/) and croak "$x must be numeric value !"; my $a = $self->{a} * $x; my $b = $self->{b} * $x; my $c = $self->{c} * $x; bless { a => $a, b => $b, c => $c, s => $subSpace->($a, $b, $c) }; } 1;