第74回 Error::Simple

第64回 Error.pm でちょっとハマったので - bingo_nakanishiの他言語出身者のためのPerl入門
ここで、dieされたものは、Error::Simpleにblessされたハッシュであることを述べた。

print $e

ハッシュであるにもかかわらず、次のように書ける。

use strict;
use Error qw(:try);

use Data::Dumper;

try {
  die 'aaaa';
}otherwise{
  my $e = shift;
  print Dumper $e;
  print $e;
};


結果:

$VAR1 = bless( {
                 '-file' => 'd.pl',
                 '-text' => 'aaaa',
                 '-line' => '7',
                 '-package' => 'Error'
               }, 'Error::Simple' );
aaaa at d.pl line 7.


そう

print $e;

で、

aaaa at d.pl line 7.


が表示されたのである。


オーバーロード

なんでこんな芸当ができるのかと思って、
Error.pmのソースを見ると

use overload (
	'""'	   =>	'stringify',
	'0+'	   =>	'value',
	'bool'     =>	sub { return 1; },
	'fallback' =>	1
);

こうなっているので、オーバーロードされていることがわかる。



さらに、Error.pmのなかに、

package Error::Simple;

@Error::Simple::ISA = qw(Error);

sub new {
    my $self  = shift;
    my $text  = "" . shift;
    my $value = shift;
    my(@args) = ();

    local $Error::Depth = $Error::Depth + 1;

    @args = ( -file => $1, -line => $2)
	if($text =~ s/ at (\S+) line (\d+)(\.\n)?$//s);

    push(@args, '-value', 0 + $value)
	if defined($value);

    $self->SUPER::new(-text => $text, @args);
}

sub stringify {
    my $self = shift;
    my $text = $self->SUPER::stringify;
    $text .= sprintf(" at %s line %d.\n", $self->file, $self->line)
	unless($text =~ /\n$/s);
    $text;
}

このように、Error::Simpleのstringifyメソッドが実装されているので、
確かに ファイル名、行番号が表示された理屈もわかる。