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

XSお勉強メモ4

perl

List::UtilのXSパートのminメソッドを読んでいたら下記のようなマクロがあった。

magic = SvAMAGIC(retsv);


SvAMAGICマクロは「sv.h」に定義されていた。

#define SvAMAGIC(sv)    (SvROK(sv) && (SvFLAGS(SvRV(sv)) & SVf_AMAGIC))

SvROK、SvFLAGS、SvRVは、下記の感じ。

  • SvROK
    • SV が RV であるかを検査します。
  • SvFLAGS
    • #define SvFLAGS(sv) (sv)->sv_flags
  • SvRV
    • SV を返すために RV を参照はずしします。


最後のSVf_AMAGICは、同じく「sv.h」の中で定義されている。

#define SVf_AMAGIC       0x10000000  /* has magical overloaded methods */

マジカルなオーバーロードされたメソッドを持っているか?
どういうことか分からなかったので、「t/min.t」を覗いてみたら、下記のようなテストがあった。

my $one = Foo->new(1);
my $two = Foo->new(2);
my $thr = Foo->new(3);

$v = min($one,$two,$thr);
is($v, 1, 'overload');

$v = min($thr,$two,$one);
is($v, 1, 'overload');

{ package Foo;

use overload
  '""' => sub { ${$_[0]} },
  '+0' => sub { ${$_[0]} },
  '<'  => sub { ${$_[0]} < ${$_[1]} },
  fallback => 1;
  sub new {
    my $class = shift;
    my $value = shift;
    bless \$value, $class;
  }
}

overloadプラグマで定義されたオブジェクトを引数に渡した時にチェックされるっぽい。