@nqounetです。
前回は LogParser クラスを作成し、ログをハッシュとして扱えるようにしました。
今回は、このクラスを機能拡張して、「特定のIPアドレスからのアクセスだけを抽出するフィルター機能」を追加してみましょう。
オブジェクト指向プログラミングの教科書通り、「継承」を使って実現してみます。
今回のゴール:IPFilteredLogParserクラス
LogParser を継承し、指定したIPアドレスにマッチするログが見つかるまで読み込み続ける IPFilteredLogParser クラスを作ります。
コード例1: IPFilteredLogParser.pm
| |
ポイント解説
extends 'LogParser': これでLogParserの機能(およびLogReaderの機能)をすべて受け継ぎます。has target_ip: フィルタリング条件となるIPアドレスを保持する新しいアトリビュートです。sub next_log: 親クラスにあるメソッドを同名で再定義(オーバーライド)しています。$self->SUPER::next_log: 親クラス(LogParser)のnext_logを呼び出しています。これを使わないと、自分自身(IPFilteredLogParser)のnext_logを再帰呼び出しして無限ループになってしまいます。
コード例2: 使用するスクリプト
| |
これで、特定のIPアドレスのログだけを簡単に抽出できるようになりました!
もし別の条件(例えばステータスコード)でフィルタリングしたい場合は、同様に StatusFilteredLogParser を作れば良さそうですね。
忍び寄る「継承の影」
今のところ、継承アプローチはとても順調に見えます。
しかし、もし以下のような要望が出たらどうなるでしょうか?
- 「IPアドレスでフィルタリングしたい」
- 「かつ、ステータスコードが404のものだけ欲しい」
あるいは、
- 「ステータスコードでフィルタリングしたい」
- 「かつ、IPアドレスは関係ない」
このように条件の組み合わせが増えてきた時、継承アプローチは突如として破綻します。
次回は、その「破綻の瞬間」を見てみましょう。
