Singleton

Tangerine::Core::Logを書くのに、デザインパターン 初めの一歩:Singleton - hibomaのはてなダイアリーとか読みながら、自分でSingletonなクラスを設計しようか、CPANモジュールを使おうかとか悩んでるところ。とりあえず今はClass::Singletonのサブクラスとして実装してます。いくつかのメソッド周りがちょっとだいぶ非常に変態的な実装になってるけど。これどうにかしないとなぁ。なんかあり得ないくらいキモい実装なんだよね。

追記 [23:47]

自分でSingletonな実装を書くとしたら、やっぱりこうなるのかなぁ。

package Tangerine::Core::Log;

use strict;
use warnings;

my $fh;
my $singleton;

sub open {
    if (!$singleton) {
        my $class = shift;
        $singleton = bless {@_}, $class;
        open $fh, '>>', $singleton->{file};
        return $singleton;
    }
    else { $singleton }
}

sub say {
    shift;
    print $fh @_, "\n" if $fh;
}

sub close {
    close $fh if $fh;
}

1;
package Tangerine::Plugin::Base;
use Tangerine::Core::Log;

sub foo {
   Tangerine::Core::Log->say('bar');
}

1;
use Tangerine::Core::Log;

my $obj = Tangerine::Core::Log->open(file => 'Tangerine.log');
$obj->say('Hello, world!');
$obj->close;

エラーチェックとか他のメソッドとか全部無視して最低限のコードだけだけど、これにしてもあんまりスマートな実装じゃない…。そもそもSingletonを使うかどうかから考え直した方がいいかなぁ。$fhをオブジェクトに持たせないのは、$obj->{fh}とか外から触れないようにしたいから。