BBRK 14-12-29


fml の makefml がエラー  

# 非スクールネタ(苦笑)

前回、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) {

以上の修正で、エラーは出なくなりましたし、ちゃんと動作してます。


BBRK に戻る / BBRK 14-12-29 の全記事に戻る