Decorator
理解の足らない部分が見えてきたけれど、兎に角23パターン全部やってみる。
use strict; use warnings; { package Display; use strict; use warnings; sub getColumns {die;} sub getRows {die;} sub getRowText {die;} sub show { my ($self, ) = @_; for(my $i=0; $i<$self->getRows(); $i++){ print $self->getRowText($i),"\n"; } } } { package StringDisplay; use strict; use warnings; our @ISA = qw/Display/; sub new { my ($class, $string) = @_; my $self = { string => $string, }; return bless $self, $class; } sub getColumns { return length($_[0]->{string}); } sub getRows { return 1; } sub getRowText { my ($self, $row) = @_; if($row == 0){ return $self->{string}; } else { return ''; } } } { package Border; use strict; use warnings; our @ISA = qw/Display/; } { package SideBorder; use strict; use warnings; our @ISA = qw/Border/; sub new { my ($class, $display, $char) = @_; my $self = { display => $display, borderChar => $char, }; return bless $self, $class; } sub getColumns { $_[0]->{display}->getColumns() + 2; } sub getRows {$_[0]->{display}->getRows();} sub getRowText{ my ($self, $row) = @_; return $self->{borderChar}.$self->{display}->getRowText($row).$self->{borderChar}; } } { package FullBorder; use strict; use warnings; our @ISA = qw/Border/; sub new { my ($class, $display) = @_; my $self = { display => $display, }; return bless $self, $class; } sub getColumns { $_[0]->{display}->getColumns() + 2; } sub getRows { $_[0]->{display}->getRows() + 2; } sub getRowText { my ($self, $row) = @_; if($row == 0){ return "+".$self->makeLine('-', $self->{display}->getColumns())."+"; } elsif($row == $self->{display}->getRows() + 1){ return "+".$self->makeLine('-', $self->{display}->getColumns())."+"; } else { return "|".$self->{display}->getRowText($row-1)."|"; } } sub makeLine { my ($self, $char, $count) = @_; my $buffer = ''; $buffer .= $char for(1..$count); return $buffer; } } use Data::Dumper; my $obj = StringDisplay->new('hogemoge'); my $obj2 = SideBorder->new($obj, '#'); my $obj3 = FullBorder->new($obj2); my $obj4 = FullBorder->new( SideBorder->new( SideBorder->new( FullBorder->new( StringDisplay->new('yorosiku-uho') ), "&" ), '!' ) ); $obj->show(); $obj2->show(); $obj3->show(); $obj4->show();