Perlのエラーメッセージのコーナー。
Perlのエラーメッセージが表示される最小のプログラムを書いて、どういうときにどう怒られるかを研究する。
(※今日のブログもスッキリ終わりません!!!)

今回のお題は
Bareword "%s" not allowed while "strict subs" in use

である。

Bare Tree Sunset
「strict subs」を使っている時、裸のワード%sは許されていない、というほどの意味である。

たとえば以下のプログラムを考えてみる。
#! /usr/bin/perl
#
# subTest.pl -- strict subsのテスト

use 5.010;
use strict;
use warnings;

&now;

say "completed";

sub now {
 say scalar localtime;
}
このプログラムはエラーにならない。
実行すると以下のようになる。
[perl]$ subTest.pl
Thu Oct 1 21:52:28 2015
completed
サブルーチンnowは、現在時刻を表示する。

それはいいのだが、下のプログラムはエラーになる。
#! /usr/bin/perl
#
# subTest.pl -- strict subsのテスト

use 5.010;
use strict;
use warnings;

now;

say "completed";

sub now {
 say scalar localtime;
}
実行してみる。
[perl]$ ./subTest.pl
Bareword "now" not allowed while "strict subs" in use at ./subTest.pl line 9.
Execution of ./subTest.pl aborted due to compilation errors.
今日のお題が出た。

これは、メインの文
&now;
についていたサブルーチンのシジル&を外したからである。

「completed」も表示されていないから、プログラムは実行されていないことがわかる。

シジル&は、省略することも出来る。
やり方としては、メインプログラムの先頭にサブルーチンの定義を移す。
#! /usr/bin/perl
#
# subTest.pl -- strict subsのテスト

use 5.010;
use strict;
use warnings;

sub now {
 say scalar localtime;
}

now;

say "completed";
あるいは、サブルーチンの宣言だけして、実装は後ろに回すこともできる。
#! /usr/bin/perl
#
# subTest.pl -- strict subsのテスト

use 5.010;
use strict;
use warnings;

sub now;

now;

say "completed";

sub now {
 say scalar localtime;
}
これでもエラーが出ない。

strict "subs"は、strict "vars"、strict "refs"と並んで、プログラムの書き方を厳しく制限する(もっともやかましくエラーを出して、プログラマーの誤りを防ぐ)strictモジュールの3大制約の1つだ。
use strict;とだけ掛けば、この3制約がすべて有効になり、最も厳しい姿勢でプログラムを書くことになる。
ではこれを外す。
#! /usr/bin/perl
#
# subTest.pl -- strict subsのテスト

use 5.010;
#use strict;
use warnings;

now;

say "completed";

sub now {
 say scalar localtime;
}
実行してみた。
[perl]$ subTest.pl
Unquoted string "now" may clash with future reserved word at /Users/query1000/perl/subTest.pl line 9.
Useless use of a constant ("now") in void context at /Users/query1000/perl/subTest.pl line 9.
completed
今度は「completed」は表示されている。
その上に表示されているのはエラーではなく警告で、warningsモジュールが表示している。
警告の意味は「クォートされていない文字列「now」は未来の予約語と衝突する可能性がある」および「定数『now』が無意味な文脈で使われている」というほどの意味だ。
use warningsも外す。
#! /usr/bin/perl
#
# subTest.pl -- strict subsのテスト

use 5.010;
#use strict;
#use warnings;

now;

sub now {
 say scalar localtime;
}

実行してみる。
[perl]$ subTest.pl
completed
なんと、無事にプログラムが終わってしまった。
サブルーチンに該当するところは、何もしないだけだ。
これは怖い!

nowをnawとつづり間違いしてみる。
#! /usr/bin/perl
#
# subTest.pl -- strict subsのテスト

use 5.010;
#use strict;
#use warnings;

naw;

sub now {
 say scalar localtime;
}
実行してみる。
[perl]$ subTest.pl
completed
これでも大丈夫である。
意味のない裸のワード「naw」をポンと書いているのを、特に警告もせずに終わってしまう。

Perlは、腕に覚えがある人はワンライナーなどのカジュアルな目的で自己責任で書く分には、strictモジュールもwarningsモジュールも使わずに、ちょいちょいと書いてしまうことが可能だ。
しかし、腕に自信のない人は、両方モジュールを付けて、満艦飾でエラーと警告を出してもらうのが安全である。

と、もっともらしいことを書く以上は、「strict "subs"を使わないとどういうお手軽なプログラムが書けるか(危険を冒して裸のワードを書くとどのようないいことがあるか)」をここに書かないと意味がないような気がするのだが、それが思いつかなかった。
スミマセン。