Perlモジュールでプライベートメソッドを作る
Perlのオブジェクト指向はかなり後付けでムリヤリ感があるんだけど、privateメソッドをモジュールに作りたいなと思った場合にどうするか。というのを調べてみた。
概要
以下、ある秘密値を取得するメソッドを隠蔽したいケースを考える。実はこのメソッドは、中で単にrand(10)しているだけなのだが、何か妙な理由があって、どうしても外部から直接はアクセスできないようにしたいこととする。
例1)アンダースコアで始まる名前にする
Perlでは暗黙の了解として、あるモジュール内の関数名がアンダースコアで始まっていれば、それは「Privateメソッドだから外から使おうとするんじゃねぇ」という意思表示である。
ということで、アンダースコアで始まるサブルーチン名で作っておけばよい。
sub _get_secret { return int(rand(10)); }
シークレットを取得する関数だ、外から使うなよ! ということで先頭をアンダースコアにしている。
もっとも、これはそういう意味にしておこうというだけなので、実際に外から使おうとすれば普通に使える。ということで、それが気にくわない人はどうするか。
例2)無名サブルーチンのリファレンスを宣言する
もう少し厳密にPrivateメソッドを作りたい場合は、perlsubドキュメントにやり方のヒントが書いてある。モジュール内で、無名サブルーチンのリファレンスを保持するレキシカル変数を作ってやれば良い。
my $secret_method = sub { return int(rand(10)); };
こうすればこの変数は、モジュールの呼び出し元からは隠蔽されているため、勝手に外から使われることは無い。
サンプルソース
まずSecret.pmというモジュールがあるとする。
#!/usr/bin/perl package Secret; use strict; use warnings; sub new { my $pkg = shift; bless { }, $pkg; } my $secret_method = sub{ return int(rand(10)); }; sub get_secret { my $self = shift; return $self->$secret_method; } 1;
で、main.plからこんな感じで使われるわけやね。
#!/usr/bin/perl use strict; use warnings; use Secret; my $obj = new Secret(); print $obj->get_secret();