Kwikiで使われているSpiffyが気になったので
テンプレートメソッドを書いてみた。
-Baseで継承すると、$self=shiftとパッケージの最後に1;をつけなくてもよくなるので、コード量が減るらしい
AbstractDisplay.pm
package AbstractDisplay;
use Spiffy -Base;
stub 'open';
stub 'print';
stub 'close';
sub display {
$self->open;
for my $i (0..4) {
$self->print;
}
$self->close;
}
CharDisplay.pm
package CharDisplay;
use AbstractDisplay -Base;
sub new {
my $char = shift;
bless {ch => $char}, $self;
}
sub open {
print "<<";
}
sub print {
print "$self->{ch}";
}
sub close {
print ">>\n";
}
StringDisplay.pm
package StringDisplay;
use AbstractDisplay -Base;
sub new {
my $str = shift;
my $w = length($str);
bless {
string => $str,
width => $w
}, $self;
}
sub open {
$self->_printline;
}
sub print {
print "|$self->{string}|\n";
}
sub close {
$self->_printline;
}
sub _printline {
print "+";
for my $i (0..$self->{width}-1) {
print "-";
}
print "+\n";
}
main.pl
1
2
3
4
5
6
7
8
9
10
11
12
13 | #!/usr/bin/perl
use strict;
use CharDisplay;
use StringDisplay;
my $d1 = CharDisplay->new('H');
my $d2 = StringDisplay->new("Hello, World.");
my $d3 = StringDisplay->new("るるるるる");
$d1->display;
$d2->display;
$d3->display;
|
で実行してみる。
<<HHHHH>>
+-------------+
|Hello, World.|
|Hello, World.|
|Hello, World.|
|Hello, World.|
|Hello, World.|
+-------------+
+---------------+
|るるるるる|
|るるるるる|
|るるるるる|
|るるるるる|
|るるるるる|
+---------------+
抽象クラスのstubは実装をサブクラスに任すときに使う。サブクラスで実装されてないとdieする。
試しに、CharDisplayのprintメソッドがないと
Method print in package AbstractDisplay must be subclassed at \
/usr/lib/perl5/site_perl/5.8.8/Spiffy.pm line 279
Spiffy::__ANON__('CharDisplay=HASH(0x9a49c28)') \
called at AbstractDisplay.pm line 12
AbstractDisplay::display('CharDisplay=HASH(0x9a49c28)') \
called at ./main.pl line 11
とエラー吐いてとまる。
コードの見通しは良くなる感じ(もうちょっと複雑なことやってみないと分からんけど。)