perl - use warnings; # -w でなくて

| 0 Comments | 0 TrackBacks | このエントリーをはてなブックマークに追加 このエントリーのはてなブックマーク件数

Original: http://blog.livedoor.jp/dankogai/archives/51068305.html

-w って何? warnings って何?

まず、以下のプログラムを見てみよう。

#!/usr/local/bin/perl
use strict;

sub distance {
    my ( $a, $b ) = @_;
    return sqrt( $a**2 + $b**2 );
}

print distance(@ARGV), "\n";
% perl scratch.pl 3 4
5

use strict;しているし、そして期待どおりに動いている。


しかし、以下の場合は期待どおりだろうか。

% perl scratch.pl 3
3

distance()は引数を二つ要求するのに、一つしか入れなくても動いてしまう。これは$bがundefとなり、数値コンテキストでは0として解釈されるため当然なのだけど、あなたは本当は$bを初期化しておきかったとする。どうすればよいか。


こういう時に活躍するのが、-wスイッチであり、use warnings;である。


まずは-wを見てみよう。

% perl -w d0.pl 3
Use of uninitialized value $b in exponentiation (**) at warnings.pl line 6.
3

確かに"Use of uninitialized value $b"という警告が出た。


次にuse warnings;を見てみよう。

% cat scratch.pl 
#!/usr/local/bin/perl
use strict;
use warnings;

sub distance {
    my ( $a, $b ) = @_;
    return sqrt( $a**2 + $b**2 );
}

print distance(@ARGV), "\n";
% perl scratch.pl 3
Use of uninitialized value $b in exponentiation (**) at warnings.pl line 7.
3

こちらもきちんと警告を出している。

-w だと何がいけないの?

それでは、なぜuse warnings;を使うべきで、-wでないのか。-wの方がuse warnings;より短いではないか。


理由は二つある。

-wは.plには有効でも.pmには有効ではない

これが一番の理由である。-wはあくまでも実行時のスイッチなので、スクリプト、すなわち実行ファイルで指定しないと有効にならない。


Distance.pm

package Distance;
use strict;

use base 'Exporter';
our @EXPORT = qw/distance/;

sub distance {
    my ( $a, $b ) = @_;
    return sqrt( $a**2 + $b**2 );
}

1;

scratch.pl

#!/usr/local/bin/perl
use strict;
use Distance;
print distance(@ARGV), "\n";

と別れている場合、-wだと.plの方で指定しないと有効にならないのだ。ところが、use warnings;であれば.pmの方で指定してもきちんと警告してくれるのだ。

no warnings 'whatever';できない

use warnings;ということは、no warnings;も存在するということである。実際これは存在し、かつレキシカルなので、以下のように局所的に警告を止めることも出来る。

sub distance {
    no warnings 'uninitialized';
    my ( $a, $b ) = @_;
    return sqrt( $a**2 + $b**2 );
}
  • wでもこれに相当することは不可能ではないが、
sub distance {
    local $^W = undef;
    my ( $a, $b ) = @_;
    return sqrt( $a**2 + $b**2 );
}

という極めて醜いものである。

まとめ

というわけで、今後スクリプトを書く時には、

use strict;
use warnings;

をお忘れなきよう。


モジュールを書くのであれば、

package MyModule;
use strict;
use warnings;

としていただきたい。ちなみにh2xsやModule::Starterを使ってモジュールを初期生成した場合、この二行は必ず入っている。あと、Mooseにはこの二行と同等の効果も含まれている。


use warnings; # and be safe!


Dan the Perl Monger

No TrackBacks

TrackBack URL: http://perl-mongers.org/MT/mt-tb.cgi/57

Leave a comment

About this Entry

This page contains a single entry by dankogai [livedoor.com] published on June 19, 2008 9:56 PM.

実用! Perlで少しでもSBMのブックマーク数を多く見せる was the previous entry in this blog.

URLを触る時は、URI(perlモジュール名)が超便利だと思う。 is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.

Categories

Pages

Creative Commons License
This blog is licensed under a Creative Commons License.
Powered by Movable Type 4.21-en