jcode.pl で「defined(%hash) is deprecated」のエラーが出る場合の対応

しばらく動作確認していなかったり、新しいサーバにこれまで使っていた CGI(Perl)を動作させるとブラウザに「500 Internal Server Error」が表示されて正常動作しないことがある。

jcode.pl で「defined(%hash) is deprecated」のエラーが出る場合の対応




1.エラーログを確認する


Perl や PHP など CGI はセキュリティの観点からエラーの内容はブラウザに表示されるようにしないことが多く、エラーが発生して正常に動作しない場合は画面が真っ白か「500 Internal Server Error」が表示される。
この状態だと何が原因かの特定が難しいが、サーバのエラーログを確認できる環境であれば解決策が見つけやすくなる。
Web サーバが Apache の場合は /var/log/httpd/error_log にあるエラーログを参照する。
今回の場合、エラーログには次のような記載があった。

defined(%hash) is deprecated at ./jcode.pl line ***)


2.エラーの原因


エラーログにある「defined(%hash) is deprecated at ./jcode.pl line ***」はプログラムの記述である defined(%hash) が非推奨になっていることを示している。
Perl のバージョンが上がったことにより発生するもので、レンタルサーバなどホスティングではサーバ運営者が Perl をアップデートしたり、新しいサーバに移設する場合は必然的に最新版の Perl がインストールされるのでこれまで動作していたプログラムでも動作しないことが起こりえる。

3.対応策


エラーログの内容から、jcode.pl の該当行(line ***)に問題があることがわかる。
「line ***」の *** は数値が入るが使っている jcode により数値が異なる。
変更箇所は 2 箇所あり、次のようにプログラムを修正すると新しい Perl でも動作するようになる。

sub z2h_euc {
 local(*s, $n) = @_;
 &init_z2h_euc unless defined %z2h_euc;
 $s =~ s/($re_euc_c|$re_euc_kana)/$z2h_euc{$1} ? ($n++, $z2h_euc{$1}) : $1/geo;
 $n;
}
 ↓
sub z2h_euc {
 local(*s, $n) = @_;
 &init_z2h_euc if !%z2h_euc;
 $s =~ s/($re_euc_c|$re_euc_kana)/$z2h_euc{$1} ? ($n++, $z2h_euc{$1}) : $1/geo;
 $n;
}


sub z2h_sjis {
 local(*s, $n) = @_;
 &init_z2h_sjis unless defined %z2h_sjis;
 $s =~ s/($re_sjis_c)/$z2h_sjis{$1} ? ($n++, $z2h_sjis{$1}) : $1/geo;
 $n;
}
 ↓
sub z2h_sjis {
 local(*s, $n) = @_;
 &init_z2h_sjis if !%z2h_sjis;
 $s =~ s/($re_sjis_c)/$z2h_sjis{$1} ? ($n++, $z2h_sjis{$1}) : $1/geo;
 $n;
}


4.対応策の内容


Perl の hash(ハッシュ)とは、他の言語でいうところの「連想配列」のことで変数名の前に % を付与して表す。
エラーにもあるプログラム内の「defined」は引数の値が定義されているかを True か False で返すものだが、Perl のバージョンが上がり非推奨となったためpログラムからは削除する。
また、プログラム内の「unless」は条件式が偽の場合に処理させたい内容を記述するもので、「unless」を廃止してより簡単にするために if 文に加えて否定を示す ! を連想配列の前に付けている。
もし「defined」を消すだけであれば連想配列の前の ! は不要となる。

ブログ気持玉

クリックして気持ちを伝えよう!

ログインしてクリックすれば、自分のブログへのリンクが付きます。

→ログインへ

なるほど(納得、参考になった、ヘー)
驚いた
面白い
ナイス
ガッツ(がんばれ!)
かわいい

気持玉数 : 0

この記事へのコメント