Perl入門ゼミ

テキスト処理、Linuxサーバー管理、Web開発ならPerl
  1. Perl
  2. オブジェクト指向
  3. 環境に応じた振る舞い

環境に応じたオブジェクトを作成する

クラスを少しだけ改造してOSに応じて振る舞いを変更するようにしてみましょう。

1. 環境に応じて振る舞いを変えるポリモーフィズム

環境がWindowsだった場合は、FilePath::Windowsクラスのオブジェクトを作成して、環境がそれ以外だったら、FilaPath::Unixクラスのオブジェクトを作成するクラスを書いてみました。

use strict;
use warnings;

my $file_path = FilePath->new;

my $result = $file_path->cat_path('a', 'b');

print "結果: $result\n";

# ユーザが利用するクラス
package FilePath;

sub new {
  my $self = shift;
  if ($^O eq 'MSWin32') {
    return FilePath::Windows->new;
  }
  else {
    return FilePath::Unix->new;
  }
}

# ファイルパスを扱うための基底クラス
package FilePath::Base;

sub new {
  my $proto = shift;
  my $class = ref $proto || $proto;
  my $self = {};
  bless $self, $class;
  return $self;
}

sub cat_path {
  my ($self, $str1, $str2) = @_;
  return $str1 . $self->delimiter . $str2;
}

# Unix 用
package FilePath::Unix;
use base 'FilePath::Base';

# Unixの場合の区切り文字
sub delimiter{ return '/' }


# Windows用
package FilePath::Windows;
use base 'FilePath::Base';

# Windowsの場合の区切り文字
sub delimiter{ return '\\' }

実行結果は、環境がWindowsの場合は、

結果: a\b

それ以外の場合は、

結果: a/b

となります。環境がWindowsの場合は、FilePath::Windowsクラスのオブジェクトが生成されて、それ以外の場合は、FilePath::Unixクラスのオブジェクトが生成されているということです。

print ref $file_path;

とするとどのクラスのオブジェクトが作成されているかが見えると思います。

2. コンストラクタで振る舞いを変える

ユーザが利用するクラスとして、FilePathというクラスを準備しました。このクラスのコンストラクタが、環境に応じたオブジェクトを生成してくれます。(一般的には、ファクトリークラスと呼ばれるものになります。)

package FilePath;

sub new {
  my $self = shift;
  if ($^O eq 'MSWin32') {
    return FilePath::Windows->new;
  }
  else {
    return FilePath::Unix->new;
  }
}

$^O を見てOSの種類を調べて、作成するオブジェクトを変更しています。この例のコンストラクタは引数を受け取りませんが、コンストラクタというのは、一般的には引数を受け取るので

sub new {
  my $self = shift;
  if ($^O eq 'MSWin32') {
    return FilePath::Windows->new(@_);
  }
  else {
    return FilePath::Unix->new(@_);
  }
}

と記述する場合のほうが多いです。3項演算子を使って書くとさらにすっきりします。

sub new {
  my $self = shift;
  return $^O eq 'MSWin32' ? FilePath::Windows->new(@_) :
                            FilePath::Unix->new(@_);
}

3. 継承の便利なところ

継承をうまく使えば、環境に応じた振る舞いをさせる記述をすっきと記述することができることがわかると思います。

また、ほかの環境にも対応させたい場合は「FilePath::ほにゃらら」というクラスを作って、FilePathクラスのコンストラクタを少し修正すれば良いだけです。

つまりどのような場面で継承が威力を発揮するかといえば、数多くのパターンが存在して、拡張の可能性が高い場面ということになります。 

4. 継承が難しいと感じる場合は

このサンプルをデバッガでたどってください。クラスの間をどういう風に動き回っているかを、観察すれば、理解できてくるはずです。

$^O の値を変えれば、Windows の場合や、Unixの場合をエミュレートできます。また、ref関数を使って、作成されたオブジェクトが属するクラスを見たりしてください。

  • Perlとはテキスト処理の記述性とパフォーマンスに優れ、正規表現が言語に組み込まれているプログラミング言語です。
  • Linuxサーバーでのフィルタリングプログラム、複数行の文字列を処理、ファイル内容の検索・置換などが得意
  • Perlはgitopensslなど広く普及したUnix/Linuxミドルウェアの補助ツールとして採用実績あり。後方互換性とポータビリティの高さがひとつの理由と推測。
  • 大量のテキストを扱うWeb開発も得意。ロングテールSEOを意識したWebサイト、アドテクやソーシャルゲームでの50ms以内のJSONの生成など。