先月にData::Dumperサポートした時には自動でオブジェクトやリファンレスをDumpしていませんでしたが、0.04で自動で行うようなオプションを設けました。

普通にログメッセージにリファレンスを渡すと

warnf({ foo => bar}); # HASH(0x100804ed0)
warnf("foo: %s",{ foo => bar}); # foo: HASH(0x100804ed0)

とrefaddrが返るだけですが、AUTODUMPフラグを有効にすると

local $Log::Minimal::AUTODUMP = 1;
warnf({foo=>'bar'}); # {'foo'=>'bar'}
warnf("dump is %s", {foo=>'bar'}); #dump is {'foo'=>'bar'}

と、Data::Dumperでシリアライズして出力します。

前回悩んでいたところの、演算子をoverloadしているオブジェクトが渡された場合ですが、sprintfのコンテキストに応じて動きを変えることで解決しました。ストリングコンテキストでは文字列化→数値化の順に試し、両方存在しない場合はdumpし、数値コンテキストでは、数値化→文字列化の順に実行し、どちらもなければそのままsprintfに投げます。

まず、リファレンスを渡した際ですが、

local $Log::Minimal::AUTODUMP = 1;
my $hashref = {foo=>'bar'};
warnf("%s : %d", $hashref, $hashref);
# => 2010-12-29T10:38:47 [WARN] {'foo' => 'bar'} : 22768536 at -e line 1

この様に、ストリングコンテキストの時はDumpされ、数値コンテキストでは、refaddrとなります。演算子オーバーロードがないオブジェクトも同様の動きです

次に、文字列変換が定義されているオブジェクトの場合、

local $Log::Minimal::AUTODUMP = 1;
my $uri = URI->new("https://blog.nomadscafe.jp/");
warnf("%s : %d", $uri, $uri);
# => Argument "https://blog.nomadscafe.jp/" isn't numeric in sprintf at /usr/.../Log/Minimal.pm line 96.
# => 2010-12-29T10:41:38 [WARN] https://blog.nomadscafe.jp/:0 at -e line 1

ストリングコンテキストはそのまま、stringfyされ出力されます、数値コンテキストでは数値化が定義されていないので、文字列化してsprintfに渡します。最終的には数値ではないので、warningが吐かれます。

最後に、数値変換ができる場合、

package Num;
use overload '0+' => sub { ${$_[0]} };
sub new {
    my ($class, $value) = @_;
    bless \$value, $class;
}

package main;

local $Log::Minimal::AUTODUMP = 1;
my $num = Num->new(654321);
warnf("%s : %d", $num, $num);
# => 2010-12-29T10:51:38 [WARN] 654321 : 654321 at /tmp/hoge.pl line 12

%sの場合に、文字列化がないので数値化して利用し、%dでは数値化が使われます。結果同じ値が返されています。

説明すると面倒ですが、使う分には問題なく使えると思います。引き続きご意見募集中。

このブログ記事について

このページは、Masahiro Naganoが2010年12月29日 11:03に書いたブログ記事です。

ひとつ前のブログ記事は「キャッシュシステムの Thundering Herd 問題への対策案。その2 排他制御」です。

次のブログ記事は「Plack::Middleware::Log::Minimal でログ出力方法をカスタマイズ可能にしました」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ

OpenID対応しています OpenIDについて
Powered by Movable Type 4.27-ja