理系学生日記

おまえはいつまで学生気分なのか

忍者TOOLS

PerlでSingleton

Perlってばお茶目なので、privateだのpublicだの基本ない感じです。
privateなメソッドは最初に_をつけるとかいう慣習もあるっぽいんですけど、もちろん外からは呼び出せる。


Singletonはそのクラスのオブジェクトを1つしか生成しないというデザインパターンで、コンストラクタをprivateにするのが定石みたいですが、Perlだとprivateとかないし、当然外からそのコンストラクタは呼び出せることになってしまう。
どうしたもんかなぁと思って悩んだ後、コンストラクタ消せばいいじゃん!!!!!!!!ってことに気づきました。
まず普通にコンストラクタを定義して1つしかないオブジェクト作った後、そのコンストラクタの中身を、さっき作ったオブジェクトを返すように変える。
BEGINの中身がそんな感じです。
いちおう、bokuで一意(?)な値を出力させるようにして確認することにします。

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;

実験コードはこんな感じ。

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