前の記事で言及したSTDIN/STDOUT を使うテストの記事に対しては、ブックマークコメントで「STDINは
」てなことも書いていたのですが、それに対して、STDIN を使うテストの記事にて以下の言及を頂きました。local *STDIN = *DATA;
もできそう。
入力パターンが1個しかないことはめったに無い
入力とそれに対する結果はなるべく近くに置きたい
たしかにその通りと思います。
なので、DATA
を使わずに、tie
でSTDIN
の入力元を配列変数に置き換えることができないものかと試してみました。
use strict;
use warnings;
{
# 入力元を配列変数に置き換えるクラス
package TESTIN;
sub TIEHANDLE {
my $class = shift;
my @lines = map { "$_\n" } @_;
bless \@lines, $class;
}
sub READLINE {
shift @{$_[0]};
}
}
# テスト対象のサブルーチン
sub add {
my $result = 0;
while( <STDIN> ) {
chomp;
$result += $_;
}
return $result;
}
# test
use Test::More 'no_plan';
# test 1 (here document)
my @in1 = split /\n/, <<'__EOT__';
1
3
5
7
9
__EOT__
{
tie local *STDIN, 'TESTIN', @in1;
is( add(), 25 );
}
# test 2 (qw() list)
my @in2 = qw( 2 4 6 8 10 );
{
tie local *STDIN, 'TESTIN', @in2;
is( add(), 30 );
}
Perlのtie
は今まであまり使ったことがなかったので、良い勉強の機会になりました。(参照: perltie(日本語訳))
関連: