グローバル変数はいつ値を割り当てられますか?

perl
グローバル変数はいつ値を割り当てられますか?

Perlスクリプトの実行と初期化の順序に関する基本的なことを理解していないことを示唆する奇妙な動作に遭遇しました。 次の例

#!/usr/bin/env perl

use strict;
use warnings;

print &get_keys(), "\n";

use vars qw/%hello/;  # same effect with 'my %hello = (...);'
%hello = ( a => 1, b => 2 );

sub get_keys
{
        return join(', ', sort keys %hello);
}

空の文字列を出力します。 つまり、変数は既に表示されていますが、割り当てられた状態にまだ到達していないため、値はありません。 (ハッシュの代わりにスカラーを使用すると、初期化されていない変数に関する警告がトリガーされます。)

それは意図した動作ですか?

RTFMポインターも嬉しいです。

  2  2


ベストアンサー

perlsubから:

_
「my」には、コンパイル時と実行時の両方の効果があります。 コンパイル時に、コンパイラはそれに注意します。 これの主な有用性は「use strict ‘vars’」を静かにすることです。 ただし、実際の初期化は実行時まで遅延されるため、適切な時間に実行されます。
_

# At this point, %hello is a lexically scope variable (the my took effect
# at compile time), but it still has no keys.
print get_keys();

my %hello = ( a => 1, b => 2 );

# Now the hash has content.
print get_keys();

sub get_keys { join ' ', keys %hello, "\n" }

その他の注意:(1)「use vars」ではなく「my」または「our」を使用する必要があります。 (2)通常の状況では、先頭にアンパサンドを付けて関数を呼び出さないでください。「&foo()」ではなく「foo()」を使用してください。

8


はい、それは意図された動作です。 %hello`に割り当てる前に get_keys() を呼び出すので、 get_keys() では%hello`は空です。 (スカラーは `undef`に初期化され、配列とハッシュはデフォルトで空に設定されます。)

`%hello`をすぐに初期化するには、BEGINブロックを使用します:

use vars qw/%hello/;
BEGIN {
    %hello = ( a => 1, b => 2 );
}

「my」(または「私たち」)を使用している場合、これは機能しないことに注意してください。

BEGIN {
    my %hello = ( a => 1, b => 2 );
}

次のように、ブロックの外側で変数を宣言する必要があるためです。

my %hello;
BEGIN {
    %hello = ( a => 1, b => 2 );
}

4


`use vars`プラグマは、コンパイル時にグローバル変数名を事前宣言します。 変数は、値を割り当てない限り未定義です。 割り当ての前に出力するので、空の文字列を取得できます。

ところで、このプラグマは廃止されました。 perldoc varsから:

_
NOTE For variables in the current package, the functionality provided
このプラグマは、Perl v5.6.0以降で使用可能な「私たちの」宣言によって置き換えられています。 perlfuncの「私たち」を参照してください。
_

3


タイトルとURLをコピーしました