何気なしにソースを眺めてみたら短かったので試してみた。
とりあえず、覚えるべきは、instance()とhas_instance()、_new_instance()のみ。
- instance()
- has_instance()
- インスタンスが生成されていない場合、undefを返す。
- _new_instance()
- インスタンスを生成する。ここに初期処理を書いてやるといいでしょう。
全然エッセンスがだけを詰めることができなかったんですが、こんな感じのコードになりました。
use common::sense; package My::Singleton; use parent 'Class::Singleton'; sub foo { my ($self, $foo) = @_; if ($foo) { $self->{foo} = $foo; } return $self->{foo}; } sub original_foo { return shift->{original_foo}; } sub original_foo_times_twice { return shift->{original_foo} * 2; } # 最初にインスタンスが生成されるときこいつが呼ばれる sub _new_instance { my $class = shift; my %args = @_; $args{foo} //= 1; $args{original_foo} = $args{foo}; return bless { %args }, $class; } 1; package main; use Perl6::Say; # インスタンスを持っているかどうか defined My::Singleton->has_instance or say 'not exist instance'; my $singleton1 = My::Singleton->instance(foo => 10); say $singleton1->foo; #=> 10 $singleton1->foo(20); say $singleton1->foo; #=> 20 say $singleton1->original_foo; #=> 10 say $singleton1->original_foo_times_twice; #=> 20 my $singleton2 = My::Singleton->instance(foo => 10); # $singleton1を書き換えても同じインスタンスなので書き換わる $singleton1->foo(30); say $singleton2->foo; #=> 30 say $singleton2->original_foo; #=> 10 say $singleton2->original_foo_times_twice; #=> 20