目の前に僕らの道がある

勉強会とか、技術的にはまったことのメモ

Class::Singletonを試してみる。

何気なしにソースを眺めてみたら短かったので試してみた。
とりあえず、覚えるべきは、instance()とhas_instance()、_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