5

いくつかのモジュールを使用して Perl でアプリを作成しています。次のように、どこからでも見えるグローバル定数をいくつか書きたいと思います。

#Constants.pm
$h0 = 0;
$scale = 20;

そして、修飾せずに、main::またはConstants::いくつかのモジュールでそれらを使用します。use Constants;ただし、複数のモジュールを記述した場合、それらは 1 つの名前空間にのみインポートされます。これを回避する方法はありますか?

最新の ActivePerl を使用しています。

4

5 に答える 5

7

Exporterperlmodman ページを確認してください。

于 2009-02-08T14:15:55.353 に答える
7

このコードのチャンクは、まさにあなたが望むことをするはずです。すべての称賛をlkundrakに送ってください。

package Constants;

use base qw/Exporter/;

use constant BOB => 666;
use constant ALICE => 555;

sub import {
    no strict "refs";

    ${[caller]->[0].'::'}{$_} = ${__PACKAGE__."::"}{$_}
        foreach grep { not /^(ISA|isa|BEGIN|import|Dumper)$/ } 
            keys %{__PACKAGE__."::"};
}
于 2011-07-06T02:25:22.467 に答える
5

私があなたにこれを言った人には言わないでください、しかしPerlの特別な変数はどこでも利用可能です。あなたはおそらくこれが機能しないことに気づいたでしょう:

{ package Foo;
our $global = 42; }

{ package Bar;
say "global is $global"; }

それ$globalは実際にはと呼ばれているからです$Foo::global。また、この「ルール」が、、、など@INCには適用されないことにも気付いたと思います 。これは、これらの変数が常ににあると想定されているためです。%ENV$_main

しかし実際には、それはそれらの変数だけではありません。グロブ全体がに「強制」されmainます。つまり、次のように書くことができます。

{ package Constants;
  $_{PI} = 3.141592; }

{ package Foo;
  say "pi is $_{PI}"; }

そしてそれは動作します。

$ENV( 、、などにも同じことが当てはまります&INC

ただし、実際のコードでこれを行う場合は、誰かがあなたを殺害することを期待してください:)ただし、他の誰かがそれを行っているのを見た場合に備えて、知っておくとよいでしょう。

于 2009-02-09T07:28:28.810 に答える
2

これを の一番上に置くことができますConstants.pm:

package main;

この場合、定義するすべての変数はmain名前空間にあります。

$main::x

または、勇気がある場合:

package;

この場合、定義するすべての変数は空の名前空間になります。

$::x

名前空間を指定せずに使用packageすることはお勧めできません。また、Perl の一部のバージョンでは非推奨になるようです。以下の引用を参照してください。


からの引用man perlfunc

       パッケージ名前空間
       package コンパイル単位が指定されたパッケージ内にあることを宣言します
               名前空間。パッケージ宣言のスコープは
               宣言自体から最後まで
               囲みブロック、ファイル、または eval (「my」と同じ)
               オペレーター)。その他のすべての非修飾動的識別子
               この名前空間になります。パッケージ ステートメントが影響を与える
               動的変数のみ - 使用したものを含む
               「ローカル」オン--しかしレキシカル変数ではありません。
               「私の」で食べました。通常、それは最初のデクラですか?
               "require" または
               「使用」演算子。より多くのパッケージに切り替えることができます
               一か所よりも; それは単にどのシンボルテーブルに影響を与えるか
               そのブロックの残りの部分でコンパイラによって使用されます。
               変数とファイルハンドルは、他の場所で参照できます。
               識別子にパッケージのプレフィックスを付けることによるパッケージ
               名前と二重コロン: $Package::Variable. もし
               パッケージ名は null です。想定される「メイン」パッケージです。
               つまり、$::sail は $main::sail と同等です (同様に
               $main'sail に関しては、まだ古いコードで見られます)。

               NAMESPACE が省略されている場合、現在のパックはありませんか?
               年齢、およびすべての識別子は完全修飾または
               語彙。ただし、使用しないことを強くお勧めします
               この機能を利用します。使用すると思わぬ事故につながる可能性があります
               Perl のいくつかのバージョンをクラッシュさせることさえあります。それは
               非推奨であり、将来のリリースから削除される予定です。


編集:この質問も役立つかもしれません: Perl モジュールの定数を使用するにはどうすればよいですか?

于 2009-02-08T11:31:25.513 に答える
2

次のようにExporterを使用できます。

Constants.pm で:

#Constants.pm
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw($h0 $scale);
@EXPORT_OK = qw(myfunc);

$h0 = 0;
$scale = 20;
sub myfunc {...}

注:
* 配列内の&in&myfunc@EXPORTオプションであり、使用しないことをお勧めします。* これはデフォルトで and をエクスポート$h0し、$scale明示的に要求された場合にのみ &myfunc をエクスポートします (クライアント モジュールによってインポートされるシンボルを指定する方法は以下を参照してください)。

次に、Constants.pm をインポートして使用したいモジュールで$h0$scaleまたは&myfunc次を追加して、Constants.pm にあるすべてのシンボルをインポートし@EXPORTます。

#MyModule.pm
use Constants qw(;

一部のシンボルのみをインポートする場合は、次を使用します。

#MyModule.pm
use Constants qw($h0);

最後に、Constant.pm のシンボルをまったくインポートしたくない場合は、次を使用します。

#MyModule.pm
use Constants ();
于 2009-02-11T20:37:53.053 に答える