2

短縮版

コード ブロックour内では非修飾名を使用するが、外部では修飾名を使用すると宣言されたモジュールから変数にアクセスすることは可能ですか? BEGIN特に、モジュール ファイルでパッケージに明示的に名前を付けずにこれを行うことはできますか?

させdemomod.pm

use strict;
use warnings;    
package demomod;
our $foo;
BEGIN { $foo = 42; }
1;

そしてdemoscript.plなる

#!/usr/bin/perl -Tw
use strict;
use warnings;
BEGIN { @INC = ('.', @INC); }
use demomod;
print $demomod::foo."\n";

この場合、すべての名前が一致し、すべてが正常に機能します。コードpackage demomod;から行を省略しても、これを機能させる方法はありますか?demomod.pm

動機

私が質問している理由は、最近のFoswikiのアップグレード中に、これらの線に沿った何かに遭遇したからです。そのソフトウェアには、を持たないモジュールがあります(編集:理由は不明ですが、ローカルコピーで行が失われただけのようです)。私の例のように、変数を宣言して初期します。と呼ばれる CGI スクリプトもあります。変数が初期化されていないため、この最後の行は常に失敗します。Foswiki.pm package package$engineview@INCuse Foswiki ();$Foswiki::engine->run()

Can't call method "run" on an undefined value at …/view

モジュールのBEGINブロックでは、$engine正しく設定されていますが、$Foswiki::engine明らかにそうではありません。したがって、ここには 2 つの変数があり、1 つは修飾され、もう 1 つは修飾されていないようです。

そのコードはすべて他の人でも機能するようで、以前のバージョンは私でも機能していましpackage。したがって、これがどのように壊れたのかを理解しようとする一方で、その線がなくても以前はどのように機能していたのかを理解しようとしています. これを機能させるメカニズムはありますか?

4

1 に答える 1

3

packageコードにステートメントがない場合、すべてのパッケージ変数がパッケージに宣言されmainます。いいえ、あなたが説明することはできません。

Foswikiリンクしたコードの 2 行目を見ると、package ステートメントがあることがわかります。

于 2013-01-07T10:33:36.413 に答える