【Perlエラーチェックポイント】Perlの実行時にエラーが出た時にまずは確認しておきたいポイント


PC/プログラム/ゲーム/ネット系レポ TOPはこちら

Perlの実行時にエラーが出たときのあるあるチェックポイント

Perlはどこでエラーが起きているかわかりにくい時があります。

さっきまで動いていたのに、突然プログラムが実行できないエラー(500)が出てしまい「どこ間違えた?」なんてことも

・・・と、いう訳で、とりあえずありがちなミスを自分の経験からまとめてみました。

エラーのチェックポイントをご紹介します。


変数名に$を付け忘れている

 エラー 

よくやりがちです。


if で { } の付け忘れ

 エラー 

特に、他の言語と違って、一行で完結するif 文でも

if (xxx==0) { 〜;  }

のように { ] が必要なので、付け忘れないようにしましょう。


( )  { } の対応がとれていない

 エラー 

括弧の対応がとれていないと、エラーが起きます。

よーく見て、if 文などで、どちらかの括弧が多い・・・かもしれません。

秀丸エディタなど、対応を分かりやすく表示してくれるエディタを使用するとこの手のエラーは減らせるかと思いますね。


; セミコロン忘れ

 エラー 

行末に ; をつけ忘れている。


; セミコロンが " "で囲まれた中に入っている

 エラー 

これは意外と分かりにくいし、原因特定に時間がかかってしまうエラーです。

"〜〜〜;〜〜〜" のように、セミコロンがダブルコーテーションの中に含まれているとエラーになっちゃいます。


注釈を // とかにしている

 エラー 

JavascriptやC++など他の言語を混在して使用をしていると間違えやすいです。

 /*  */ としてしまうことも。Perlの注釈は # です。


"〜' と "〜' など対応が取れていない

 エラー 

"〜〜〜〜'; といった具合に、シングルコーテーション(')とダブルコーテーション(")がごっちゃになっている場合があります。


"〜" と '〜' の動きの違いを間違っている

"\n" だと改行文字だけども、 '\n' とすると、そのまま \n で出力されてしまいます。

エスケープ文字などを使用する場合は、"〜" を使います。

"〜" の中で、" を使用したいときは、 \" とします。

※このページでは、使用フォント等によって、¥マークがバックスラッシュ(\)となって表示されていると思いますが、¥マークもバックスラッシュ(\)も同じです。


"〜" の中に " がある。\" にし忘れている

 エラー 

HTML関係のコードをPRINT "〜〜〜"; の形式で記述するとよく発生します。

\"にするのが面倒な場合は、シングルコーテーション ' ' で囲む方が楽です。

print '<table border="1" cellspacing="0" cellpadding="5" width="590" bgcolor="#FFFEDD" >';

でも、変数展開やエスケープシーケンスは ' ' で囲むとできません。HTMLの場合は " " でくくらなくても動作してしまいます。そのため、

print "<table border=1 cellspacing=0 cellpadding=5 width=590 bgcolor=#FFFEDD >\n";

みたいにいっそのこと "" を抜いてしまうというのも手です。


変数展開に失敗している

 想定外動作 

稀に"〜" で囲んで変数を中に入れると、変数展開時に間違って認識されてしまうことがあります。

そんなときは、$変数名 を ${変数名}  と記載して、明確にすることで間違って認識されることがなくなります。

複雑な展開をする場合は、書式化に対応した sprintf(・・・); を使用する方がいいでしょう。


スペースだと思ったら全角漢字の空白(" ")だった、全角のセミコロン(;)だった

 エラー 

これも結構あるあるです。

全角スペースが見えるエデッタの使用や、全角スペースで検索するなどして、チェックしてみてください。


サーバ上の属性変更(実行属性への変更)を忘れていた

 そもそも実行できないエラー 

サーバで実行属性に変更し忘れていることあるあるです。

サーバにperlのファイルをアップロードした後に、属性変更をし忘れていると実行ファイルと識別されずに実行できません。

perlプログラムを実行する場合、実行できるようにパーミッションを 705 や 707 に変更する必要があります。

CGIは、実行できるようにパーミッションを 705 や 707 に変更する必要があるのですが、それを忘れると実行できません。利用しているレンタルサーバによって、パーミッションに指定があるので、確認しましょう。

拡張子の指定があるときは、その拡張子にしておきます。たとえば .cgi にするなどです。

(ホームページ運営会社によって異なります。さくらインターネットの場合は705に変更して、指定の拡張子にする必要があります)


FTP「バイナリーモード」で転送していた

 そもそも実行できないエラー 

cgiプログラムをFTPで「バイナリーモード」で転送すると実行できない場合があります。

その場合、「アスキーモード」にして転送します。

FFFTPでは、拡張子ごとに転送モードを設定する機能などもあります。


perl のパスが間違っていた

 そもそも実行できないエラー 

テストしている環境と、実際のサーバで、perlのパスが違う時は、修正しておきましょう。


漢字・2バイト文字が化ける(表示→侮ヲ)

 想定外動作   エラー 

実行時エラーではないですが、文字が化けるときがあります。

特に「表示」という文字。「侮ヲ」になってしまいます。(ヲは半角)

print "表示";  → 「侮ヲ」

こんな時は

print "表\示";  → 「表示」

print '表示";  → 「表示」

として対処します。

また、文字列を大文字にする関数もありますが、日本語処理に対応していない通常の uc(); などを使用すると、漢字が化けます。

注意なのは、シングルコーテーションでくくっても、文字の最後に「ダメ文字」が含まれているとエラーになってしまいます。はっきり言って、ダメ文字が原因でエラーとなると、原因がわかるまでめちゃくちゃ大変です。

【ダメ文字の例】print でダブルコーテーションで表示すると正しく表示されない(化ける)、または、文末に入っているとエラーになってしまう文字

「予」 予定 ⇒ 予\定

「表」 表示 ⇒ 表\示
    予定表 ⇒ 予\定表\

「ソ」 パソコン ⇒ パ\ソ\コン

「欺」 詐欺 ⇒詐欺\

「能」 芸能 ⇒芸能\

「十」 十円 ⇒十\円

「圭」 圭  ⇒圭\

「申」 申込 ⇒申\込

「蚕」 蚕  ⇒蚕\

「暴」 暴行 ⇒暴\行

「噂」 噂 ⇒ 噂\

「―」 ― ⇒ ―\

「構」 構造 ⇒構\造

「貼」 貼付 ⇒貼\付

「禄」 元禄 ⇒元禄\

「拿」 拿捕 ⇒拿\捕

「\」 \ ⇒\\  などです・・・


日本語が正しく検索されない

 想定外動作 

$temp_string の文字中に、$temp_keyword の文字を含んでいたら・・・

if ( $temp_string =~ /$temp_keyword/ ) {   }

・・・という処理を実行しようとしても、$temp_keyword に SHIFT-JISの"ー" (のばす文字)や "表" や "暴" の文字が入ると、文字列処理がうまくいかない。

そんな時は、内部変数に変換して、

use Encode 'decode';
$temp_string = decode ('Shift_JIS' , $temp_string ); # 内部変数に変換
$temp_keyword = decode ('Shift_JIS' , $temp_keyword ); # 内部変数に変換
if ( $temp_string =~ /$temp_keyword/ ) {・・・}

とするとよいです。

ページの文字コードをSHIFT-JISに設定している場合など、表示するときにSHIFT-JIS に戻す必要があるときは、

$temp_string = encode ('Shift_JIS' , $temp_string );
$temp_keyword = encode ('Shift_JIS' , $temp_keyword );
print "$temp_string\n";
print "$temp_keyword \n"; 

とします。


漢字が化ける、生成したWebページがprintで表示されない

 想定外動作 

Perlのプログラムから、HTMLのコードを生成するときに、「Content-Type: text/html; charset=Shift_JIS';」を出力し忘れると 、ページが表示されないです。

print 'Content-Type: text/html; charset=Shift_JIS';
print "\n\n";
print "<html>\n";
print "<head>\n";

という感じで出力を忘れないように。(漢字コードの指定も間違えると化けるので、ご注意を。Windows系のコードの場合はSHIFT-JIS、UNIX系の場合はEUCを指定します)


同じ文字列変数のはずなのに イコールにならない(制御コードが入っている)

 想定外動作 

同じ文字列変数のはずなのに、なぜかイコールとならない・・・。

そんな場合は制御コードが文字列変数に入ってしまっている可能性があります。

# 制御文字を削除
$STR =~ s/[[:cntrl:]]//smg;

文字列に含まれている制御コードを削除する必要があります。

文字列に意図しない空白が含まれている

 想定外動作 

文字列を結合した際になぜか「空白」が含まれている・・・。そんな時は、そんな場合は制御文字が文末に入っている可能性があります。

それを消す専用の関数があります。

# 文末の制御文字を削除
chomp ($str) ;

他にノウハウがあれば、追記していきます。