目の前に僕らの道がある

勉強会とか、技術的にはまったことのメモ

テスト駆動開発入門をPerlで写経してみた。 4

今回はインスタンス変数を直接アクセスせずに比較できるように変更しています。

ただ、インスタンス変数amountのプライベート化をどうすれば実現できる分からなかったので、運用回避という形をとっています。やろうと思えばアクセスできてしまいます。

Perlの特性上(というか私の発想の限界)から原書の変更以外にも演算子をオーバーロードしてtimes()メソッドやequals()ではなく演算子を使用するように変更しています。

is()関数が内部でeq演算子を使用しているため、今回eq演算子もオーバーロードしていますが、設計上これは正しい判断なのかちょっと判別つきません。

lib/Money.pm

package Money;
use strict;
use warnings;

use version;
our $VERSION = qv('0.0.3');

1;

package Dollar;
use strict;
use warnings;

use overload
    "==" => \&equals,
    "eq" => \&equals,
    "!=" => \&not_equals,
    "ne" => \&not_equals,
    "*"  => \&times,
    '""' => \&string;

sub new {
    my ($class, $opts) =(@_);
    return bless $opts, $class;
}

sub times {
    my ($self, $multiplier) = (@_);
    return new Dollar({amount => $self->{amount} * $multiplier});
}

sub equals {
    my ($self, $dollar) = (@_);
    return $self->{amount} == $dollar->{amount};
}

sub not_equals {
    my ($self, $dollar) = (@_);
    return not $self->equals($dollar);
}

sub string {
    my ($self) = (@_);
    return $self->{amount} . ' (' . __PACKAGE__ . ')';
}

1;

t/01money.t

test_multiplication()で一時変数をインライン化しています。

test_equality()では、equals()メソッドではなく ==、!= 演算子を使ってわかりやすくしました。

use strict;
use warnings;

use Test::Class;

Test::Class->runtests;

package TestMoney;
use strict;
use warnings;

use base 'Test::Class';

use Money;
use Test::More;

sub test_multiplication : Test(2) {
    my $five    = new Dollar({amount => 5});
    is($five * 2, new Dollar({amount => 10}));
    is($five * 3, new Dollar({amount => 15}));
}

sub test_equality : Test(2) {
    ok(new Dollar({amount => 5}) == new Dollar({amount => 5}));
    ok(new Dollar({amount => 5}) != new Dollar({amount => 6}));
}

1;

関連


テスト駆動開発入門

テスト駆動開発入門

  • 作者: ケントベック,Kent Beck,長瀬嘉秀,テクノロジックアート
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2003/09
  • メディア: 単行本
  • 購入: 43人 クリック: 1,002回
  • この商品を含むブログ (153件) を見る