22

一度に 1 つずつリストすることなく、すべてのサブを名前空間に公開したいと思います。

@EXPORT = qw( firstsub secondsub third sub etc );

完全修飾名を使用すると、既存のコードに多くの変更が必要になるため、私はそれを行いません。

@EXPORT_ALLはありますか?

ドキュメンテーションはそれは悪い考えだと言っていると思いますが、とにかくやりたい、または少なくとも方法を知りたいです。

Jon の理由に答えるには: 今すぐリファクタリングを迅速に行うために、既存のスクリプトへの手間とコードの変更を最小限に抑えて、多数のサブを独自のパッケージに移動したいと考えています (これらのサブは現在使用されており、頻繁に繰り返されます)。

また、ほとんどの場合、私はただ興味がありました。(Exporterには標準機能としてそれがあるように見えたので、これまでの回答に基づいて驚くべきことにそうではありません)

4

9 に答える 9

10

しないでください。しかし、本当に必要な場合はimport、シンボルテーブルをウォークし、名前の付いたすべてのサブルーチンをエクスポートするカスタムを作成します。

# Export all subs in package. Not for use in production code!
sub import {
    no strict 'refs';

    my $caller = caller;

    while (my ($name, $symbol) = each %{__PACKAGE__ . '::'}) {
        next if      $name eq 'BEGIN';   # don't export BEGIN blocks
        next if      $name eq 'import';  # don't export this sub
        next unless *{$symbol}{CODE};    # export subs only

        my $imported = $caller . '::' . $name;
        *{ $imported } = \*{ $symbol };
    }
}
于 2009-04-09T00:15:10.927 に答える
3

警告、次のコードはすべてをエクスポートするのと同じくらい悪い考えです:

package Expo;

use base "Exporter";

seek DATA, 0, 0; #move DATA back to package

#read this file looking for sub names
our @EXPORT = map { /^sub\s+([^({\s]+)/ ? $1 : () } <DATA>;

my $sub = sub {}; #make sure anon funcs aren't grabbed

sub foo($) {
    print shift, "\n";
}

sub bar ($) {
    print shift, "\n";
}

sub baz{
    print shift,"\n";
}

sub quux {
    print shift,"\n";
}

1;

__DATA__

モジュールを使用するコードは次のとおりです。

#!/usr/bin/perl

use strict;
use warnings;

use Expo;

print map { "[$_]\n" } @Expo::EXPORT;

foo("foo");
bar("bar");
baz("baz");
quux("quux");

そして、ここにその出力があります:

[foo]
[bar]
[baz]
[quux]
foo
bar
baz
quux
于 2009-04-08T23:09:30.710 に答える
2

完全に指定された形式でいつでもサブルーチンを呼び出すことができます。

MyModule::firstsub();

私が内部で作成するモジュールの場合、この規則はかなりうまく機能することがわかります。タイピングは少し多いですが、ドキュメントの方が優れている傾向があります。

perldoc perlmodあなたが達成しようとしていることについてのより多くの情報を見てください。

より一般的には、Exporterのコードを見て、globエイリアシングがどのように使用されているかを確認できます。または、モジュールの名前空間を調べて、各サブルーチンをエクスポートすることもできます。(現時点では、その方法を探す必要はありませんが、Perlを使用すると、これをかなり簡単に行うことができます。)または、サブルーチンをmainパッケージに貼り付けることもできます。

 package main;
 sub firstsub() { ... }

(それは良い考えではないと思いますが、あなたは私があなたが達成しようとしていることをするよりもよく知っています。)

自分が何をしているのかを知っていて、外の世界へのインターフェースについて考えることを避けようとしているのでなければ、これを行うことに何の問題もありません。

于 2009-04-08T22:33:36.130 に答える
2

https://metacpan.org/pod/Exporter::Auto

エクスポーター::自動。必要なのはこれだけです。

于 2014-10-11T18:23:01.537 に答える
2

おそらく、サブ定義に属性を追加するだけでサブをエクスポート可能としてマークできる、CPAN の Export* モジュールの 1 つに興味があるでしょうか? (ただし、それがどれだったかは覚えていません。)

于 2009-04-09T01:29:04.413 に答える
1

すべての s をモジュールから呼び出し元の名前空間にダンプすることは通常は賢明ではありませんが、変数と変数subを自動的に生成すると便利な場合があります (さらに DRY!) 。@EXPORT_OK%EXPORT_TAGS

最も簡単な方法は、エクスポーターを拡張することです。簡単な例は次のようなものです。

package Exporter::AutoOkay;
#
#   Automatically add all subroutines from caller package into the
#   @EXPORT_OK array. In the package use like Exporter, f.ex.:
#
#       use parent 'Exporter::AutoOkay';
#
use warnings;
use strict;
no strict 'refs';

require Exporter;

sub import {
    my $package = $_[0].'::';

    # Get the list of exportable items
    my @export_ok = (@{$package.'EXPORT_OK'});

    # Automatically add all subroutines from package into the list
    foreach (keys %{$package}) {
        next unless defined &{$package.$_};
        push @export_ok, $_;
    }

    # Set variable ready for Exporter
    @{$package.'EXPORT_OK'} = @export_ok;

    # Let Exporter do the rest
    goto &Exporter::import;
}

1;

これを使用するとgoto、呼び出し元スタックから削除されることに注意してください。

より完全な例がここにあります: http://pastebin.com/Z1QWzcpZサブルーチンのプレフィックスからタグ グループを自動的に生成します。

于 2013-04-02T00:32:25.440 に答える
-1

いくつかの型グロブ変更を行う必要があります。ここで似たようなことを説明します:

単一のファイルを「使用」して、Perl で他の複数のファイルを使用する方法はありますか?

そこにあるインポート ルーチンは、あなたが望むことを正確に実行する必要があります。ただし、独自の名前空間にシンボルをインポートしないでください。

于 2009-04-08T22:47:28.670 に答える