Perlってばお茶目なので、privateだのpublicだの基本ない感じです。 privateなメソッドは最初に_をつけるとかいう慣習もあるっぽいんですけど、もちろん外からは呼び出せる。
Singletonはそのクラスのオブジェクトを1つしか生成しないというデザインパターンで、コンストラクタをprivateにするのが定石みたいですが、Perlだとprivateとかないし、当然外からそのコンストラクタは呼び出せることになってしまう。 どうしたもんかなぁと思って悩んだ後、コンストラクタ消せばいいじゃん!!!!!!!!ってことに気づきました。 まず普通にコンストラクタを定義して1つしかないオブジェクト作った後、そのコンストラクタの中身を、さっき作ったオブジェクトを返すように変える。 BEGINの中身がそんな感じです。 いちおう、bokuで一意(?)な値を出力させるようにして確認することにします。
|perl| package Singleton; use strict;
our $singleton;
BEGIN { sub new { bless { num => 1 }, shift; } $singleton = Singleton->new(); $Singleton::{new} = sub { return $singleton; }; }
sub boku { my $self = shift; print "ぼくです!!$selfです!!\n"; }
sub plus { my $self = shift; $self->{num} += shift; }
1; ||<
実験コードはこんな感じ。
|perl| use Singleton;
my $boku1 = Singleton->new(); $boku1->boku(); print $boku1->plus( 5 ), "\n";
my $boku2 = Singleton->new(); $boku2->boku(); print $boku2->plus( 5 ), "\n"; ||< これ、できてるかな?なんかとんでもないことを見落としているようなきもします。
|| ぼくです!!Singleton=HASH(0x818040)です!! 6 ぼくです!!Singleton=HASH(0x818040)です!! 11 ||<