use strict; を使う理由

今更な気がしますが、より多くの人がuse strict;でハッピーになれますように。

use strict; はブラボーなおまじない

use strict; と書くだけで以下の3つが機能します。

  1. use strict "vars";
  2. use strict "refs";
  3. use strict "subs";

1. use strict "vars"; の機能

変数を宣言しないままに使用するとエラーになる機能です。エラーにしないためには、次のいずれかを守って変数を使います。

  • "our"または"my"を使って変数をあらかじめ宣言する。
  • "vars"プラグマを使って使う変数を宣言したのち、"local"で変数を宣言する。
  • パッケージ名を含めて変数を書く。

確実な書き方の例

use strict;
use warnings;

our $ours;
my $mine;

use vars qw($locals);
local $locals;

$main::fully_name = "hello, world!";
print $main::fully_name;

では、この機能は何が便利なのでしょうか。答えは、変数名のタイプミスを見つけてくれる事です。これで変数名のタイプミスを探す必要は無くなりました。ブラボー!

変数名を間違えた例

use strict;
use warnings;

my $hello = "hello, world!"; 
print $hell;
# "hello"と"hell"を間違えた。

起きるエラー

Global symbol "$hell" requires explicit package name at ... line 5.

なお、use strict; とuse warnings; が無い場合、なにも表示されずに正常終了します。

2. use strict "refs"; の機能

シンボリックリファレンス(ソフトリファレンス)を禁止する機能です。シンボリックリファレンスとは、変数名を別の変数に入れておき、その変数をデリファレンスすることで、代入された変数名の実体にアクセスする機能です。代入されている変数名を変更することで、ダイナミックに変数にアクセスする仕組みを提供します。

シンボリックリファレンス例

$christmas = "merry, christmas!";
$new_year  = "happy, new year!";
$easter    = "happy, easter!";

$greeting = "new_year";
print ${$greeting};

実行結果

happy, new year!

とはいえ、問題が起きたときに原因特定が困難なこと、レキシカル変数(myで宣言した変数)を参照できないこと、多くはハッシュや配列で代用可能なことから、できるだけ使わないようにする機能の一つです。*1
では、シンボリックリファレンスを禁止すると何が便利なのでしょうか。答えは、デリファレンスしすぎを見つけてくれるようになる事です。これでデリファレンスを適当に書いてもエラーで止まってくれます*2。ブラボー!

デリファレンスに間違いがある例

use strict;
use warnings;

my $greeting = {
	christmas => "merry, christmas!",
	new_year  => "happy, new year!",
	easter    => "happy, easter!",
};

# 変数の構造はこんな感じだった?
print $greeting->{new_year}->{string};

起きるエラー

Can't use string ("happy, new year!") as a HASH ref while "strict refs" in use at ... line 11.

なお、use strict; とuse warnings; が無い場合、なにも表示されずに正常終了します。

3. use strict "subs"; の機能

ベア(裸の)ワードの詩的な最適化を禁止します。詩的な最適化とは、Perlコンパイル中にトークン(文字列、数値、演算子、関数、変数などなど)に分類できない文字の並びに出くわしたとき、適当に解釈してくれる機能です。その機能を禁止します。

ベアワードでサブルーチンを指定

$call = hello_world;
$call->();
# hello_world->(); というのも有効。ここら辺がperlのフリーダムな所。

sub hello_world { print "hello, world!\n" }

実行結果

hello, world!

ベア(裸の)ワードは、Perl*3を書くときには便利ですが、プログラムにおいては、ほとんど利点がありません。
ベア(裸の)ワードを禁止すると何が便利なのでしょうか。答えは、あまり便利にはなりません。とはいえ、$%@などの書き忘れや、"=>"演算子の左項の間違いぐらいは見つけてくれます。ブラボー!

"=>"演算子の左項の書き方を間違えた例

use strict;
use warnings;

my %hash = (foo-1 => "alpha", bar_2 => "bravo"); 
# "foo_1"をうっかり"foo-1"と書いてしまった。
print $hash{foo_1};
Bareword "foo" not allowed while "strict subs" in use at ... line 4.

なお、use strict; とuse warnings; が無い場合、なにも表示されずに正常終了します。

use strict; しませんか?

何故なら、その方がカッコイイから!ブラボー!

*1:Damian Conway, Perlベストプラクティス, O'REILLYオライリージャパン, 2006,11.3 シンボリック参照

*2:よい子は、最初からきちんと書きましょう

*3:詩のように見えて、Perlコンパイラを通るプログラム