BBRK 14-12-29
# 非スクールネタ(苦笑)
前回、BBRK で記事にしたのは、BBRK 07-04-07。
そのときは、管理プログラム makefml を実行しても特に問題はなかったのですが、インストール以来 7年ぶりに実行してみたら、エラーが…(苦笑)
■症状
bash-2.05$ ./makefml defined(@array) is deprecated at ./makefml line 4357. (Maybe you should just omit the defined()?) defined(%hash) is deprecated at ./makefml line 4368. (Maybe you should just omit the defined()?) defined(%hash) is deprecated at ./makefml line 4371. (Maybe you should just omit the defined()?) Can't locate getopts.pl in @INC (@INC contains: /usr/local/lib/perl5/5.16/BSDPAN /usr/local/lib/perl5/site_perl/5.16/mach /usr/local/lib/perl5/site_perl/5.16 /usr/local/lib/perl5/5.16/mach /usr/local/lib/perl5/5.16 .) at ./makefml line 104. bash-2.05$ |
perldiag - さまざまな Perl 診断メッセージ によると、エラーメッセージの意味は…、
defined(@array) is deprecated (D deprecated) defined() は未定義の スカラ 値を調べるので、配列に 使っても普通は無意味です。 配列が空かどうかを調べたい場合は、例えば単に if (@array) { # not empty } としてください。 defined(%hash) is deprecated (D deprecated) defined() は未定義の スカラ 値を調べるので、ハッシュに 使っても普通は無意味です。 ハッシュが空かどうかを調べたい場合は、例えば単に if (%hash) { # not empty } としてください。 Can't locate %s (F) ファイルを do (または、require、use) するように 指示されましたが、見つかりませんでした。 Perl は、フルパスで指定されていない場合ファイルを @INC で示される 全ての場所を検索します。 おそらく、追加ライブラリの場所を示すために、 PERL5LIB または PERL5OPT の環境変数を指定する必要があるか、 スクリプトの中で @INC にライブラリ名を追加する必要があります。 ファイル名のスペルミスの可能性もあります。 "require" in perlfunc と lib を参照してください。 |
えっ? あたさ、何もいじってないのに、なんで?? …と調査を進めてみると(笑)、Perl の version5.11(あたり)以降から仕様が変わり、warning を出すようになった模様。
そういえばウチのレンタルサーバは 2013年8月に Perl が 5.16 にバージョンアップしたんだっけ。
■対処
/fml/makefml の各行を修正。
(1) モジュールの呼び出し方の変更
場所 | 修正前 | 修正後 |
104行 | require 'getopts.pl'; | use Getopt::Std; |
105行 | &Getopts("dhf:A:O:p:D:vwV:mi:u:UF"); | getopts('dhf:A:O:p:D:vwV:mi:u:UF'); |
(2) defined の warning
最近の Perl の仕様変更により、配列が空かどうか調べるのに defined を使うことや、ハッシュが空かどうか調べるのに defined を使うことが非推奨になったために出ている警告。
Perlの組み込み関数 defined の翻訳 によると、
集合(ハッシュや配列)への defined の使用は非推奨です。 これはその集合にメモリが割り当てられたかを報告するのに 用いられていました。 この振る舞いは将来のバージョンの Perl では消滅するかもしれません。 代わりにサイズに対する簡単なテストを使うべきです。 if (@an_array) { print "has array elements\n" } if (%a_hash) { print "has hash members\n" } ハッシュの要素に対して用いると、value が定義されているか否かを 返すものであって、ハッシュに key が存在するか否かを返すのではありません。 この用途には、exists を使ってください。 |
ということなので、下記のように修正。
場所 | 修正前 | 修正後 |
4357行 | if (defined @entry) { | if (@entry) { |
4366行 | $key ne "_$package" && $key ne "_DB" && defined %entry | $key ne "_$package" && $key ne "_DB" && %entry |
4371行 | (defined %entry) && | (%entry) && |
でもって、実行すると、/fml/cf/config にも同じように修正必要な箇所が…(苦笑)
/fml/cf/config の各行を修正。
場所 | 修正前 | 修正後 |
20行 | require 'getopts.pl'; | use Getopt::Std; |
21行 | &Getopts("m:hdDr:csnfrFI:v"); | getopts('m:hdDr:csnfrFI:v'); |
611行 | elsif (defined @entry) { | elsif (@entry) { |
614行 | elsif (defined %entry) { | elsif (%entry) { |
657行 | if (defined @entry) { | if (@entry) { |
672行 | if ($key ne "_$package" && defined %entry) { | if ($key ne "_$package" && %entry) { |
745行 | elsif (defined @entry) { | elsif (@entry) { |
748行 | elsif ($key ne "_$package" && $key ne "_DB" && defined %entry) { | elsif ($key ne "_$package" && $key ne "_DB" && %entry) { |
以上の修正で、エラーは出なくなりましたし、ちゃんと動作してます。