読者です 読者をやめる 読者になる 読者になる

Perl日記

PerlとかRubyとかPHPとかPythonとか

overloadでマジックデクリメントその2

昨日の続き。
overload - Perl の演算子のオーバーロードを行うパッケージ - perldoc.jp

Fallback



(フォールバック)
"fallback"は、特定の演算子に対するメソッドが見つからない場合の動作を規定します。 "fallback" の value によって、3 つの場合があります:

  • undef

Perl は、代替のメソッドを使うことを試みます (MAGIC AUTOGENERATION の節を参照してください)。それもダメならば、"nomethod" を呼び出そうとします。これも無い場合には、例外が発生することになります。

  • TRUE

(真)
undef の場合と同じですが、例外を発生させません。この場合、黙って、もし use overload がなかったときに、行なってであろう動作に戻されることになります。

  • define,but FALSE

(定義済みだが「偽」)
マジック自動生成は行ないません。 Perl は、まず "nomethod" の実行を試みて、これがなければ、例外を発生させます。

上記を読んで、昨日のはメソッドが見つからないときのfallbackでdieしてる感じなのがわかった。
というわけで fallback => 1 してみたら通常処理はうまく動いた。

MagicDecrement.pm

package MagicDecrement;
use strict;
use warnings;
use overload
  q(-)  => \&minus,
  q(--) => \&decrement,
  q("") => \&double_quote,
  fallback => 1
;

sub import {
  overload::constant(
    integer => \&integer,
  );
}
sub unimport {
  overload::remove_constant(
    integer => \&integer,
  );
}

sub integer {
  my ($orig, $interp, $context) = @_;
  bless { integer => $interp }, __PACKAGE__;
}

sub minus {
  my ($minus1, $minus2) = @_;
  bless { integer => $minus1->{integer} - $minus2->{integer} }, __PACKAGE__;
}

sub decrement {
  my ($dec) = @_;
  $dec->{integer} = $dec->{integer} - 1;
  bless { integer => $dec->{integer} }, __PACKAGE__;
}

sub double_quote { $_[0]->{integer} }

1;
__END__
#!/usr/bin/env perl
use strict;
use warnings;
use 5.010;
use MagicDecrement;

my $i = 21;
my $j = 12;
say $i - $j; #=> 9

$i--;
say $i; #=> 20


ちなみにoverloadは「多重定義」という意味らしい。
なんか擬似ハッシュみたいな感触。
使ったこと無いけど。


まだ続く。


参考:
http://blog.livedoor.jp/dankogai/archives/51268304.html