NAME ¶
perllexwarn - Perl Lexical Warnings
perllexwarn - Perl のレキシカルな警告
説明¶
The use warnings
pragma enables to control precisely what warnings are to be enabled in which parts of a Perl program. It's a more flexible alternative for both the command line flag -w and the equivalent Perl variable, $^W
.
use warnings
プラグマは、Perl プログラムのある部分に対してどの警告を 有効にするかを精密に制御できるようにします。 これはコマンドラインオプション -w および等価な Perl 変数 $^W
よりも より柔軟な代替案です。
This pragma works just like the strict
pragma. This means that the scope of the warning pragma is limited to the enclosing block. It also means that the pragma setting will not leak across files (via use
, require
or do
). This allows authors to independently define the degree of warning checks that will be applied to their module.
このプラグマはちょうど strict
プラグマと同様に動作します。 つまり、警告プラグマのスコープは閉じたブロック内に限定されます。 また、プラグマ設定は (use
, require
, do
を通して)ファイルを超えて 漏洩することはありません。 これにより、モジュール作者は警告チェックの度合いを独立に 設定できるようになります。
By default, optional warnings are disabled, so any legacy code that doesn't attempt to control the warnings will work unchanged.
デフォルトでは、オプションの警告は無効なので、警告を制御しようとしない レガシーコードは変更なしで動作します。
All warnings are enabled in a block by either of these:
あるブロック内で全ての警告を有効にするには以下のどちらかのようにします:
use warnings;
use warnings 'all';
Similarly all warnings are disabled in a block by either of these:
同様に、あるブロック内で全ての警告を無効にするには以下のどちらかのように します:
no warnings;
no warnings 'all';
For example, consider the code below:
例えば、以下のコードを考えます:
use warnings;
my @a;
{
no warnings;
my $b = @a[0];
}
my $c = @a[0];
The code in the enclosing block has warnings enabled, but the inner block has them disabled. In this case that means the assignment to the scalar $c
will trip the "Scalar value @a[0] better written as $a[0]"
warning, but the assignment to the scalar $b
will not.
外側のブロックでは警告は有効ですが、内側のブロックでは無効です。 この場合、スカラ $c
への代入では "Scalar value @a[0] better written as $a[0]"
警告が出ますが、 スカラ $b
への代入では出ません。
デフォルトの警告とオプションの警告¶
Before the introduction of lexical warnings, Perl had two classes of warnings: mandatory and optional.
レキシカル警告の説明の前に、Perl は二つの警告クラスがあります: 強制的(mandatory)とオプション(optional)です。
As its name suggests, if your code tripped a mandatory warning, you would get a warning whether you wanted it or not. For example, the code below would always produce an "isn't numeric"
warning about the "2:".
名前が示しているように、コードが強制的な警告に引っかかると、望むと 望まな意図にかかわらず警告を出力します。 例えば、以下のコードは "2:" の部分に対して常に "isn't numeric"
警告を 出力します。
my $a = "2:" + 3;
With the introduction of lexical warnings, mandatory warnings now become default warnings. The difference is that although the previously mandatory warnings are still enabled by default, they can then be subsequently enabled or disabled with the lexical warning pragma. For example, in the code below, an "isn't numeric"
warning will only be reported for the $a
variable.
レキシカルな警告の導入によって、強制的な警告は デフォルトの 警告と なりました。 違いは、以前の強制的な警告は今でもデフォルトで有効ですが、引き続く レキシカルな警告プラグマで有効/無効にに出来ることです。 例えば、以下のコードでは、"isn't numeric"
警告は $a
変数に対してだけ 報告されます。
my $a = "2:" + 3;
no warnings;
my $b = "2:" + 3;
Note that neither the -w flag or the $^W
can be used to disable/enable default warnings. They are still mandatory in this case.
-w オプションや $^W
はデフォルトの警告を無効/有効にするのには 使えないことに注意してください。 この場合は強制的なままです。
What's wrong with -w and $^W
¶
(-w や $^W
の何が悪いの?)
Although very useful, the big problem with using -w on the command line to enable warnings is that it is all or nothing. Take the typical scenario when you are writing a Perl program. Parts of the code you will write yourself, but it's very likely that you will make use of pre-written Perl modules. If you use the -w flag in this case, you end up enabling warnings in pieces of code that you haven't written.
警告を有効にするのにコマンドラインで -w を使うというのはとても 便利ですが、オールオアナッシングであるという問題があります。 Perl のプログラムを書いているときのよくある状況を考えます。 コードの一部はあなた自身が書きますが、かなり確実に既に書かれている Perl モジュールを利用します。 このような場合に -w フラグを使うと、あなたが書いていないコードに 対しても警告を有効にすることになります。
Similarly, using $^W
to either disable or enable blocks of code is fundamentally flawed. For a start, say you want to disable warnings in a block of code. You might expect this to be enough to do the trick:
同様に、コードブロックで有効または無効にするために $^W
を使うことにも 本質的な欠点があります。 まず、コードブロックで警告を無効にしたいとします。 以下のようにすれば十分だと考えるかもしれません:
{
local ($^W) = 0;
my $a =+ 2;
my $b; chop $b;
}
When this code is run with the -w flag, a warning will be produced for the $a
line -- "Reversed += operator"
.
このコードが -w フラグ付きで実行されると、$a
の行で警告が 出ます -- "Reversed += operator"
。
The problem is that Perl has both compile-time and run-time warnings. To disable compile-time warnings you need to rewrite the code like this:
問題は、Perl にはコンパイル時警告と実行時警告があると言うことです。 コンパイル時警告を無効にするには、以下のようにコードを書き直す必要が あります:
{
BEGIN { $^W = 0 }
my $a =+ 2;
my $b; chop $b;
}
The other big problem with $^W
is the way you can inadvertently change the warning setting in unexpected places in your code. For example, when the code below is run (without the -w flag), the second call to doit
will trip a "Use of uninitialized value"
warning, whereas the first will not.
$^W
に関するもう一つの問題は、コード中の予想外の位置の設定で不用意に 警告設定が変わるということです。 例えば、以下のコードが(-w フラグなしで)実行されると、doit
の 2 回目の呼び出しで "Use of uninitialized value"
警告が出ますが、 1 回目では出ません。
sub doit
{
my $b; chop $b;
}
doit();
{
local ($^W) = 1;
doit()
}
This is a side-effect of $^W
being dynamically scoped.
これは $^W
が動的スコープを持つことの副作用です。
Lexical warnings get around these limitations by allowing finer control over where warnings can or can't be tripped.
レキシカルな警告は、どこで警告に引っかかるか引っかからないかに関して より精度の高い制御をすることで、これらの制限を回避します。
コマンドラインから警告を制御する¶
There are three Command Line flags that can be used to control when warnings are (or aren't) produced:
いつ警告が発生する(あるいは発生しない)かを制御するために使われる 三つのコマンドラインフラグがあります:
- -w
-
This is the existing flag. If the lexical warnings pragma is not used in any of you code, or any of the modules that you use, this flag will enable warnings everywhere. See "Backward Compatibility" for details of how this flag interacts with lexical warnings.
これは既存のフラグです。 レキシカル警告プラグマがあなたのコードやあなたが使っているモジュールの どこでも 使われていない なら、このフラグは全ての場所で警告を 有効にします。 このフラグがレキシカル警告とどのように相互作用するかに関する詳細については "Backward Compatibility" を参照してください。
- -W
-
If the -W flag is used on the command line, it will enable all warnings throughout the program regardless of whether warnings were disabled locally using
no warnings
or$^W =0
. This includes all files that get included viause
,require
ordo
. Think of it as the Perl equivalent of the "lint" command.コマンドラインで -W フラグが使われると、プログラム中で
no warnings
や$^W =0
を使って警告を無効にしていても無視して、全ての 警告を有効にします。 これはuse
,require
,do
経由で読み込まれる全てのファイルにも 適用されます。 Perl 用の "lint" コマンドの等価物と考えられます。 - -X
-
Does the exact opposite to the -W flag, i.e. it disables all warnings.
正確に -W フラグの逆を行います; つまり、全ての警告を無効にします。
後方互換性¶
If you are used with working with a version of Perl prior to the introduction of lexically scoped warnings, or have code that uses both lexical warnings and $^W
, this section will describe how they interact.
レキシカルスコープ警告が導入される前のバージョンの Perl で動作させていたり、 レキシカル警告と $^W
の両方のコードがある場合、この節はこれらが どのように相互作用するかを記述しています。
How Lexical Warnings interact with -w/$^W
:
レキシカル警告と -w/$^W
の相互作用:
-
If none of the three command line flags (-w, -W or -X) that control warnings is used and neither
$^W
or thewarnings
pragma are used, then default warnings will be enabled and optional warnings disabled. This means that legacy code that doesn't attempt to control the warnings will work unchanged.警告を制御する三つのコマンドラインフラグ (-w, -W or -X) の どれも使われておらず、
$^W
や thewarnings
プラグマも使われていない 場合、デフォルトの警告が有効になり、オプションの警告は無効になります。 これにより、警告を制御しようとしないレガシーコードは無変更で動作します。 -
The -w flag just sets the global
$^W
variable as in 5.005 -- this means that any legacy code that currently relies on manipulating$^W
to control warning behavior will still work as is.5.005 から -w フラグはグローバルな
$^W
変数を設定します -- これにより、 警告の振る舞いを制御するために$^W
を操作することに依存している レガシーコードはそのままで動作します。 -
Apart from now being a boolean, the
$^W
variable operates in exactly the same horrible uncontrolled global way, except that it cannot disable/enable default warnings.真偽値になったことは別として、
$^W
変数は正確に同じ恐ろしく 制御不能なグローバルな方法で操作しますが、デフォルトの警告を有効化/ 無効化することは出来ません。 -
If a piece of code is under the control of the
warnings
pragma, both the$^W
variable and the -w flag will be ignored for the scope of the lexical warning.コード片が
warnings
プラグマの制御下にある場合、$^W
変数と -w フラグの両方はレキシカル警告のスコープで無視されます。 -
The only way to override a lexical warnings setting is with the -W or -X command line flags.
レキシカル警告設定を上書きする唯一の方法は -W または -X コマンドラインフラグを使うことです。
The combined effect of 3 & 4 is that it will allow code which uses the warnings
pragma to control the warning behavior of $^W-type code (using a local $^W=0
) if it really wants to, but not vice-versa.
3 & 4 の組み合わせの効果により、本当に警告したいときに $^W 型のコードの 警告の振る舞いを (local $^W=0
を使って) 制御するために warnings
プラグマを使えますが、逆はできません。
カテゴリ階層¶
A hierarchy of "categories" have been defined to allow groups of warnings to be enabled/disabled in isolation.
「カテゴリ」の階層は、警告のグループを分離して警告を有効/無効にできるように するために定義されています。
The current hierarchy is:
現在の階層は:
all -+
|
+- closure
|
+- deprecated
|
+- exiting
|
+- glob
|
+- io -----------+
| |
| +- closed
| |
| +- exec
| |
| +- layer
| |
| +- newline
| |
| +- pipe
| |
| +- unopened
|
+- misc
|
+- numeric
|
+- once
|
+- overflow
|
+- pack
|
+- portable
|
+- recursion
|
+- redefine
|
+- regexp
|
+- severe -------+
| |
| +- debugging
| |
| +- inplace
| |
| +- internal
| |
| +- malloc
|
+- signal
|
+- substr
|
+- syntax -------+
| |
| +- ambiguous
| |
| +- bareword
| |
| +- digit
| |
| +- parenthesis
| |
| +- precedence
| |
| +- printf
| |
| +- prototype
| |
| +- qw
| |
| +- reserved
| |
| +- semicolon
|
+- taint
|
+- threads
|
+- uninitialized
|
+- unpack
|
+- untie
|
+- utf8
|
+- void
Just like the "strict" pragma any of these categories can be combined
"strict" プラグマと同様、これらのカテゴリは組み合わせることができます
use warnings qw(void redefine);
no warnings qw(io syntax untie);
Also like the "strict" pragma, if there is more than one instance of the warnings
pragma in a given scope the cumulative effect is additive.
これも "strict" プラグマと同様、現在のスコープに複数の warnings
プラグマの実体があるときは、効果は加算されます。
use warnings qw(void); # only "void" warnings enabled
...
use warnings qw(io); # only "void" & "io" warnings enabled
...
no warnings qw(void); # only "io" warnings enabled
To determine which category a specific warning has been assigned to see perldiag.
ある特定の警告がどのカテゴリに割り当てられているかを知るには perldiag を参照してください。
Note: In Perl 5.6.1, the lexical warnings category "deprecated" was a sub-category of the "syntax" category. It is now a top-level category in its own right.
注意: Perl 5.6.1 では、レキシカル警告カテゴリ "deprecated" は "syntax" カテゴリの副カテゴリでした。 今ではそれ自体でトップレベルカテゴリです。
致命的警告¶
The presence of the word "FATAL" in the category list will escalate any warnings detected from the categories specified in the lexical scope into fatal errors. In the code below, the use of time
, length
and join
can all produce a "Useless use of xxx in void context"
warning.
カテゴリ一覧中に "FATAL" の文字があると、レキシカルスコープで 指定されたカテゴリで検出された全ての警告を致命的エラーに昇格させます。 以下のコードでは、time
, length
, join
の使用は全て "Useless use of xxx in void context"
警告を出力します。
use warnings;
time;
{
use warnings FATAL => qw(void);
length "abc";
}
join "", 1,2,3;
print "done\n";
When run it produces this output
実行すると、以下の出力を生成します
Useless use of time in void context at fatal line 3.
Useless use of length in void context at fatal line 7.
The scope where length
is used has escalated the void
warnings category into a fatal error, so the program terminates immediately it encounters the warning.
length
が使われているスコープでは void
警告カテゴリを致命的エラーに 昇格させるので、この警告に出会うとプログラムは直ちに終了します。
To explicitly turn off a "FATAL" warning you just disable the warning it is associated with. So, for example, to disable the "void" warning in the example above, either of these will do the trick:
明示的に "FATAL" 警告をオフにするには、単に関連する警告を無効にします。 それで、例えば、上述の例で "void" 警告を無効にするには、以下の二つの 技のどちらかを使います:
no warnings qw(void);
no warnings FATAL => qw(void);
If you want to downgrade a warning that has been escalated into a fatal error back to a normal warning, you can use the "NONFATAL" keyword. For example, the code below will promote all warnings into fatal errors, except for those in the "syntax" category.
致命的エラーに昇格した警告を通常の警告に降格させたい場合、 "NONFATAL" きーわーどが使えます。 例えば、以下のコードは "syntax" カテゴリ以外の全ての警告を致命的エラーに 昇格させます。
use warnings FATAL => 'all', NONFATAL => 'syntax';
モジュールから警告を報告する¶
The warnings
pragma provides a number of functions that are useful for module authors. These are used when you want to report a module-specific warning to a calling module has enabled warnings via the warnings
pragma.
warnings
プラグマはモジュール作者にとって有用ないくつかの関数を 提供します。 warnings
プラグマ経由で有効になったモジュール固有の警告を呼び出し元に 報告するときに使われます。
Consider the module MyMod::Abc
below.
以下の MyMod::Abc
モジュールを考えます。
package MyMod::Abc;
use warnings::register;
sub open {
my $path = shift;
if ($path !~ m#^/#) {
warnings::warn("changing relative path to /var/abc")
if warnings::enabled();
$path = "/var/abc/$path";
}
}
1;
The call to warnings::register
will create a new warnings category called "MyMod::abc", i.e. the new category name matches the current package name. The open
function in the module will display a warning message if it gets given a relative path as a parameter. This warnings will only be displayed if the code that uses MyMod::Abc
has actually enabled them with the warnings
pragma like below.
warnings::register
の呼び出しにより、"MyMod::abc" という名前の新しい 警告カテゴリを作成します; つまり、新しいカテゴリ名は現在のパッケージ名に 一致します。 このモジュールの open
関数は、引数として相対パスが与えられると 警告メッセージを出力します。 この警告は、MyMod::Abc
を使うコードが 以下のようにして warnings
によって有効にされた場合にのみ出力されます。
use MyMod::Abc;
use warnings 'MyMod::Abc';
...
abc::open("../fred.txt");
It is also possible to test whether the pre-defined warnings categories are set in the calling module with the warnings::enabled
function. Consider this snippet of code:
また、warnings::enabled
関数を使って、既に定義されているカテゴリが 呼び出しモジュールで設定されているかどうかをテストすることも可能です。 以下のコード片を考えます:
package MyMod::Abc;
sub open {
warnings::warnif("deprecated",
"open is deprecated, use new instead");
new(@_);
}
sub new
...
1;
The function open
has been deprecated, so code has been included to display a warning message whenever the calling module has (at least) the "deprecated" warnings category enabled. Something like this, say.
open
関数は非推奨なので、呼び出しモジュールで (少なくとも) "deprecated" 警告カテゴリが有効のとき警告を出力するコードが含まれています。 つまりこんな感じです。
use warnings 'deprecated';
use MyMod::Abc;
...
MyMod::Abc::open($filename);
Either the warnings::warn
or warnings::warnif
function should be used to actually display the warnings message. This is because they can make use of the feature that allows warnings to be escalated into fatal errors. So in this case
実際に警告メッセージを出力するには、warnings::warn
関数と warnings::warnif
関数のどちらかを使うべきです。 これは、警告を致命的エラーに昇格させる機能を使えるようにするためです。 それで、このような場合:
use MyMod::Abc;
use warnings FATAL => 'MyMod::Abc';
...
MyMod::Abc::open('../fred.txt');
the warnings::warnif
function will detect this and die after displaying the warning message.
warnings::warnif
関数はこれを検出して、警告を出力した後 die します。
The three warnings functions, warnings::warn
, warnings::warnif
and warnings::enabled
can optionally take an object reference in place of a category name. In this case the functions will use the class name of the object as the warnings category.
三つの警告関数 warnings::warn
, warnings::warnif
, warnings::enabled
は、オプションとしてカテゴリ名の代わりにオブジェクトの リファレンスをとることができます。 この場合関数は警告カテゴリとしてオブジェクトのクラス名を使います。
Consider this example:
この例を考えます:
package Original;
no warnings;
use warnings::register;
sub new
{
my $class = shift;
bless [], $class;
}
sub check
{
my $self = shift;
my $value = shift;
if ($value % 2 && warnings::enabled($self))
{ warnings::warn($self, "Odd numbers are unsafe") }
}
sub doit
{
my $self = shift;
my $value = shift;
$self->check($value);
# ...
}
1;
package Derived;
use warnings::register;
use Original;
our @ISA = qw( Original );
sub new
{
my $class = shift;
bless [], $class;
}
1;
The code below makes use of both modules, but it only enables warnings from Derived
.
以下のコードは両方のモジュールを使っていますが、Derived
からの警告だけを 有効にしています。
use Original;
use Derived;
use warnings 'Derived';
my $a = Original->new();
$a->doit(1);
my $b = Derived->new();
$a->doit(1);
When this code is run only the Derived
object, $b
, will generate a warning.
このコードが Derived
オブジェクトからのみ実行されているとき、 $b
は警告を出力します。
Odd numbers are unsafe at main.pl line 7
Notice also that the warning is reported at the line where the object is first used.
オブジェクトが最初に使われた行で警告が報告されることにも注意してください。
SEE ALSO¶
作者¶
Paul Marquess