私はこの質問を見ていて、遊んでいるときにこれに出くわしました:
#! /usr/bin/env perl
#
# use warnings;
use strict;
use feature qw(say);
{
our $foo = "bar";
say "Foo = $foo";
}
say "Foo = $foo"; # This is line #12
はい、use warnings;
電源を切りました...
これを実行すると、次のようになります。
Variable "$foo" is not imported at ./test.pl line 12.
Global symbol "$foo" requires explicit package name at ./test.pl line 12.
Execution of ./test.pl aborted due to compilation errors.
うーん...同じ「変数 "$foo" は ./test.pl 行 12 にインポートされていません。 」というエラーが表示されmy $foo = "bar";
ます。ブロックを離れるとmy
変数がないため、使用するとこれを理解できます。$foo
ただし、our
変数はパッケージスコープであると想定されています。$foo
その時点で価値がないかもしれないことは理解できましたが、これは?
また、「Variable "$foo" is not import at ./test.pl line 12.」はどういう意味ですか? パッケージとインポートについては理解していますが、ここにはパッケージが 1 つしかありませんmain
。パッケージ$foo
に入っている必要があります。main
インポートする必要はありません。
スコープ外になった後、パッケージに含まれていないように見えるパッケージ変数で何が起こっていますか?
補遺
したがって、 を使用
$::foo
したり、 で別のエイリアスを作成したりしour $foo;
た場合、プログラムは期待どおりに動作します。cmj
これを試してみましょう...
#! /usr/bin/env perl
#
# use warnings;
use strict;
use feature qw(say);
{
our $foo = "bar";
say "Foo = $foo";
}
our $foo; # Redeclared
say "Foo = $foo"; # This is line #12
これで、次のように出力されます。
bar
bar
回答したすべての人が指摘したように、同じ名前のパッケージ変数にエイリアスour
を作成するだけで、レキシカルスコープです。つまり、エイリアスが範囲外になると、withの値にアクセスできなくなります。それは私が今まで気づかなかったことです。$main::foo
$foo
ただし、 cjm が指摘したように、再宣言our $foo;
するとエイリアスが復元され、既存の$main::foo
は新しい にエイリアスされます$foo
。再宣言するour $foo;
と、 の値$foo
が復元されます。
our
これは、非常に紛らわしい変数の 1 つです。宣言が表示our $foo;
され、突然その変数が存在するだけでなく、不思議な値が含まれています。プログラムを検索して、その値がどこから来たのかを確認する必要があります。