How to collect exportable functions

モジュールがエクスポートする関数を集めたい、と思うことがある*1
すべてのモジュールがExporterを使っているなら、 @EXPORT_OK を見るだけでいいのだが、実際にはそうはいかない。しかたがないので、一旦他のパッケージにエクスポートし、その後コードリファレンスを回収する、という手法を取るほかない。このとき、同じパッケージを再利用できるように、処理が終わったらパッケージをクリアするのがベストプラクティスであろう。立つ鳥跡を濁さず、というやつだ。
以前のXslate::Utilでは一般的に使えるimport_form()を定義していたので、ここにコードを張っておく。今はXslate特有のコードが入ったため、コードが複雑になり、一般性も失ってしまった。

# from Text::Xslate 0.1029
sub import_from {
    my $code = '';

    # T::X::U::_importのstashをローカライズ
    # スコープを出るとパッケージは自動的にクリアされる
    local $Text::Xslate::Util::{'_import::'};

    # evalするコードを組み立てる
    for(my $i = 0; $i < @_; $i++) {
        $code .= "use $_[$i]";
        if(ref $_[$i+1]){
            $code .= sprintf ' qw(%s)', join ' ', @{$_[++$i]};
        }
        $code .= ";\n";
    }

    my $e = do {
        local $@;
        # T::X::U::_importにエクスポート
        eval  qq{package}
            . qq{ Text::Xslate::Util::_import;\n}
            . $code;
        $@;
    };
    Carp::confess("Xslate: Failed to import:\n" . $code . $e)
        if $e;

    # コードリファレンスを回収
    my @funcs = map {
            my $glob_ref = \$Text::Xslate::Util::_import::{$_};
            my $c = ref($glob_ref) eq 'GLOB'
                ? *{$glob_ref}{CODE}
                : undef;
            defined($c) ? ($_ => $c) : ();
        } keys %Text::Xslate::Util::_import::;

    return @funcs;
}
# import_from('Data::Dumper' => ['Dumper'])
# => ( Dumper => \&Data::Dumper::Dumper )

*1:たとえば、Xslateのmodule オプションなど