続・importとExporterの食い合わせが悪い?

importとExporterの食い合わせが悪い? - だるろぐ跡地で神からブックマークコメントでこんなことを教えられる。

一応こうしたらいけるけど。 http://gist.github.com/88613

どれどれ。動いた。
なるほど、Mod3でimportを作ったから、Exporter::importをオーバーライドしてしまってたのが悪かったのね。
だからExporter::importを呼んで、本来の動作をしてやったと。

名前空間

use Moduleは以下に等しい。

BEGIN { require Module; import Module LIST; }

先の例では、mainパッケージにsub p{}が無かったのが悪いわけだ。
だが、Mod3の中でExporter::importを呼んだら、Mod3の名前空間の中にExporter::importの中身が展開されるのではないか?
そんなときのcallerだ。

caller?何それおいしいの

% perldoc -f caller
…
($package, $filename, $line) = caller;
…

Mod3.pm

package Mod3;
use strict;
use warnings;

use base qw/Exporter/;
use Data::Dumper;

sub import {
    pkg();
    goto &pkg;

    strict->import;
    warnings->import;

    goto &Exporter::import;
}

our @EXPORT = qw/p/;

sub p {warn Dumper shift}

sub pkg {print join ' ', caller}

1;

実行

% perl -le 'use Mod3'
Mod3 Mod3.pm 9
main -e 1


なるほど、普通に関数呼び出しするとそのモジュールのパッケージ名が渡るが、goto &methodだと呼んだ側のパッケージ名が渡っている。
gotoがどんなものかはperldoc -f gotoしたら心が折れたので404 Blog Not Found:perl - to goto or not to goto, that's the continuationを見て満足した。



っていうことを柔道家にいつも通りお世話になりつつ学んだ。
あとWeb::ScraperをパクったMod4は、

Exporterは継承する以外にも機能あるから。それを使わず、メソッドが使えるようにしたいだけなら、あれで十分

と。

あと、

そもそも、Exporterにはexport_to_levelっていうメソッドがあるから、それ使えばいいよ

と。


神と柔道家ありがとう。

ていうか、俺よ

ソース嫁
POD嫁


今度読むよ!