- 勅使河原
3
- 隊長
2
- 勅使河原
1
- 隊長
どかーん
- 勅使河原
わーい
- 隊長
週刊オブジェクト~。始まるよ~。
- 勅使河原
(スパーン)
- 隊長
あいたっ…何をするんだい勅使ウサギ君。
- 勅使河原
勅使ウサギは置いとくとして、週刊オブイェクトのパクリか貴様?!
- 隊長
ははは、パクリとは酷いなあ。週間オブジェクトなら既出なのでそういわれても仕方がないのだが。
- 勅使河原
そっちは二重に間違えてます……orz
- 隊長
それはともかく、勅使ウサギ君。本番中だということを留意するように。ではデザインパターンの勉強をしようじゃないか。
- 勅使河原
でざいんぱたーん?
- 隊長
うむ。プログラム設計時にありがちな問題に対してどう解決したらいいかというアリガチパターンをまとめたものだと思っておけばいいね。再利用しやすかったり、メンテナンスしやすくなってとてもいいものなのだよ。
- 勅使河原
へー、それはすごいやー
- 隊長
勅使ウサギ君はなにやら投槍風味だな。今日のお題は Iterator パターン としよう。
- 勅使河原
Iterator パターン?なにがなんだかわからないやー。なにしろぼくうさぎだしー。
- 隊長
うむ、その無表情な悲哀ぶりが着ぐるみとマッチして良い演技である。
Iterator パターンというのは、とある『物の集合』に含まれている『物』に繰り返しアクセスして何かの処理を行う時に使うんだ。『集合に順番にアクセスする』部分を切り離しておくんだ。
そうすると、例えば単なる順番じゃなく、アイウエオ順にしたいとか、大きい順にしたいとかの希望があっても『集合に順番にアクセスする』部分を入れ替えればいくらでも対応できるんだ。
それに、『物の集合』自体に変更があっても『物の集合』を使っているのは『集合に順番にアクセスする』部分だけだから、そこだけ直せばいいんだよ。- 勅使河原
うわー、たいちょーさん、それはべんりだねー。
- 隊長
それじゃあ、例を見てみようか。
- 勅使河原
はーい。
use strict; package 本; use base qw(Class::Accessor Class::Fields); use fields qw(名前 説明 出版社); __PACKAGE__->mk_accessors(__PACKAGE__->show_fields('Public')); #end package 本 package 本棚; # Concrete Aggregate sub new { bless {_books=>[]}, shift }; sub append_book { my ($class, $book) = @_; push(@{ $class->{_books} }, $book); } sub get_book_at{ my ($self, $index) = @_; $self->{_books}->[$index]; } sub get_length{ $#{$self->{_books}}; } sub get_iterator{ my $self = shift; return 本棚イテレータ->new(shift); } #end package 本棚 package 本棚イテレータ; sub new { my ($class, $bookshelf) = @_; bless { _bookshelf => $bookshelf, _index => 0 }, $class }; } sub next { my $self = shift; my $shelf = $self->{_bookshelf} my $ret_book = ($shelf->get_length < $self->{_index}) ? undef : $shelf->get_book_at($self->{_index}); return $ret_book; } #end package 本棚イテレータ package main; my $審議棚 = 本棚->new; $審議棚->append_book(本->new( {名前=>'週刊オブジェクト', 説明=>'コメンツスクラーム!', 出版社=>'ひたすら無題',})); $審議棚->append_book(本->new( {名前=>'週刊オブイェクト', 説明=>'主力戦車はT-72', 出版社=>'JSF',})); $審議棚->append_book(本->new( {名前=>'歴史教科書', 説明=>'国民はよく働き、よく戦った', 出版社=>'扶△社',})); my $親の会 = $審議棚->get_iterator(); while (my $本 = $親の会->next) { if($本->説明 =~ /戦/){ print '炎 ', $book->名前, ' 炎', "\n"; } }
- 隊長
本と、本棚、本棚イテレータを準備してみたよ。
- 勅使河原
よりによって、perl で書きますか…。
- 隊長
それほど珍しくもないがびみょーに斬新風味でいいだろう、勅使ウサギ君。で、実行結果はこうなるね。
炎 週刊オブイェクト 炎 炎 歴史教科書 炎
- 隊長
ふふふ、見事な焚書ぶり。
- 勅使河原
こらーっ?!ナニやってますかぁあんたはっ?!っていうか、無関係の週刊オブイェクトまで燃えてますよ?!
- 隊長
ははは、さすが親の会はセメントだなぁ。戦の文字を見れば容赦無用だね、勅使ウサギ君。
- 勅使河原
容赦無用だねじゃないでしょ?!もっと穏便にっ!!
- 隊長
ううむ、しかし困ったな……親の会は戦争賛成っぽいと思ったら問答無用で火をつけてしまう上に、修正に応じてくれるかどうかわからないセメント人種。しかも、ココにいるものたちの他にもどれだけ大量の焚書家が控えているかもわからないぞ?
……しかし安心していいよ、勅使ウサギ君。やっててよかったIterator パターン。- 勅使河原
……なんでそういうイヤな説明をしますか。
- 隊長
さあ、親の会が次の本を見ようとするときに、危うい本は中身を読めないように隠してしまうのだっ。
sub next { my $self = shift; my $shelf = $self->{_bookshelf} my $ret_book = ($shelf->get_length < $self->{_index}) ? undef : $shelf->get_book_at($self->{_index}); # ここから if ($ret_book && $ret_book->説明 =~ /戦/){ my $新説明 = $ret_book->説明 $新説明 =~ s/戦/●/; $ret_book->説明($新説明) } # ここまで return $ret_book; }
- 隊長
これで、親の会にチェックを頼んでも、どの本も燃やされないぞ。
しかも親の会一人一人に頭を下げなくても全然オッケー。修正はほんの一箇所。どうだい?勅使ウサギ君。とっても簡単だろう。- 勅使河原
うわー、戦の文字がなくなるだけなのにとっても単純だね、親……って、なんですくわこの危険な台本はっ?!(ばしん)
- 隊長
Iterator パターンのこと、わかったかな?それじゃあ、みんな。またみてね~。
- 勅使河原
だれかとめて……orz
そんなことよりも、一話目で死んだ兄がサヨブラックとして登場したりとか、最終回で「兄さんアースはあるよ」とか、その一回前にサヨファイアが「お前は変えてみせろ」とかカッコイイ台詞を吐いて死ぬとかそういう燃える展開を希望。
ほら、みんな技系の内容なんて期待してませんから。多分。とかいいつつ次はPerl/TKでネット右翼を燃やすとか銅だろう