2012-03-07 1 views
6

use strict; use warnings;を追加した後でコードが機能しないのはなぜですか?それを動作させる方法はありますか?perlコマンドラインパラメータのエラーを回避して厳密に使用する方法

以前は、作業コードは次のとおりです。私は走った

#!/usr/bin/perl -s 
print "x: $x\n"; 
print "y: $y\n"; 

コマンドはperl -s test.pl -x="hello" -y="world"です。出力は次のとおりです。私はuse strict; use warnings;を追加した後

x: hello 
y: world 

しかし、私は次のエラーを得た:

Variable "$x" is not imported at test.pl line 4. 
Variable "$y" is not imported at test.pl line 5. 
Global symbol "$x" requires explicit package name at test.pl line 4. 
Global symbol "$y" requires explicit package name at test.pl line 5. 
Execution of test.pl aborted due to compilation errors. 

私は3番目と4番目のエラーを修正するためにmy $xmy $yを宣言する必要があります知っています。しかし、最初の2つのエラーは何を意味し、どのように私はそれを克服するのですか?

+1

私は_Mastering Perl_の章全体をあなたのオプション(heh)に割きます。 :) –

+0

シバン線が間違っています。それは#!/ usr/bin/env perlでなければなりません。最大限の移植性のための新しい行で –

+0

@briandfoy Perl_:Perlプログラムの設定の第10章ですか? –

答えて

4

グローバル変数を使用する初歩的なスイッチパーサーperl -sを使用しています。 use strictと動作させるには、グローバルを参照する必要があります:$main::x ruakhが指摘しています。

しかし、そうであっても、ほぼすべてのケースで字句変数(myと宣言されています)が適しています。

use strict; 
use warnings; 

my ($x, $y) = @ARGV; 
print "x: $x\n"; 
print "y: $y\n"; 

をとして使用します:ちょうど行うGetopt::Longモジュールをチェックアウトし、より詳細について

perl test.pl hello world 

とハンドリングのように切り替えます。

+0

良いキャッチ。私は急いで「-s」に気付かなかった。 +1 – DVK

+0

Re: "それは' use strict'と互換性があるかどうかは疑問です。方法については私の答えを参照してください。 :-) – ruakh

+0

幸運、私は私の足で死んでいます。 =) – TLP

2

Perlのエラー/警告の意味を理解するには、perldiagを参照してください。

は、具体的には、 "インポートされていない"、それは言う:実際に "厳格な使用" で

変数 "%s" はインポートされません%S

(W雑貨)同じ名前の名前(通常はサブルーチン)がそのモジュールによってエクスポートされるため、別のモジュールからインポートされたと思われるグローバル変数を参照しました。これは通常、変数の前に間違った面白い文字を置くことを意味します。

基本的には、Perlはあなたの$x identifyer非宣言し、約2つの明確な推測をした - それは

  1. パッケージスコープのグローバルstrict(「グローバル・シンボルの下で使用が禁止されてのいずれかでした"$ x"は明示的なパッケージが必要です ")

  2. 他のパッケージの変数をインポートしようとしましたが、そうではありませんでした("変数 "$ xはインポートされません)。

Perlは、2つの理論がどれほど正しいかを伝えることはできませんので、両方の可能性を吐き出してください。後者のエラー(グローバルシンボル "$ x"は明示的なパッケージ名が必要です)はこの場合正しいものでした。元のプレストリティコードのグローバル変数でした。

9

実際に、これらの変数を字句(my)変数として宣言すると、遅すぎるため、役に立たなくなります。-sスイッチで既に設定されています。それは(、あなたのケースで$main::x$main::y、または特別な速記— $::x$::yなど—)グローバル(パッケージ)変数を設定します。

our ($x, $y); 
print "x: $x\n"; 
print "y: $y\n"; 
:あなたは彼らのパッケージ修飾名を使用してそれらを参照する必要がしたくない場合は、裸の名前 $x$yは、現在のパッケージに $x$yを参照することを示すために our宣言を使用することができます

(ハットヒントは、あなたがこのためにourを使用することができることを指摘しderobertします。)

また、あなたは同じ名前のレキシカル変数にグローバル変数をコピーすることができます。

my ($x, $y) = ($::x, $::y); 
print "x: $x\n"; 
print "y: $y\n"; 

これにより、両方の診断が処理されます。

+2

'our($ x、$ y)'もうまくいくはずです。(テストしていません) – derobert

+0

@derobert:あなたは大丈夫です。私はテストして、恥知らずに私の答えを盗んだ。ありがとう! :-) – ruakh

関連する問題