見出し画像

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

Perlはどこでエラーが起きているかわかりにくい時があります。さっきまで動いていたのに、突然プログラムが実行できないエラー(500)が出てしまい「どこ間違えた?」なんてことも・・・と、いう訳で、とりあえずありがちなミスを自分の経験からまとめてみました。
エラーのチェックポイントをご紹介します。

筆者が作成している以下のサイトもよければご覧ください。
https://repo5.com/report/misc/perl_error/

基本のチェックポイント

【エラー発生】変数名に$を付け忘れている。

やりがちなミスです。でもたまにやってしまいます。

【エラー発生】if で { } の付け忘れ

Perlは他の言語と違って、一行で完結するif 文でも
if (xxx==0) { ~; }
のように { } が必要なので、忘れないようにしましょう。

【エラー発生】( ) { } の対応がとれていない

これも良くやりがちなミスですね。
秀丸エディタなど、コードを分析してくれるエディタを使用するとこの手のエラーは減ると思います。

【エラー発生】; セミコロン忘れ

これも良くやりがちなミスですね。

【エラー発生】; セミコロンが " "で囲まれた中に入っている

これは意外と分かりにくいし、原因特定に時間がかかってしまうエラーです。
"~~~;~~~" のように、セミコロンがダブルコーテーションの中に含まれているとエラーになっちゃいます。

【エラー発生】注釈を // とかにしている

JavascriptやC++など他の言語を使用しているとうっかりやってしまいます。
/* */ としてしまうことも。Perlの注釈は # です。

【エラー発生】"~' と "~' など対応が取れていない

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

【エラー発生】"~" と '~' の動きの違いを間違っている

"\n" だと改行文字だけども、 '\n' とすると、そのまま \n で出力されてしまいます。エスケープ文字などを使用する場合は、ダブルコーテーション "~" を使います。
ダブルコーテーション"~" の中で、" を使用したいときは、 \" とします。
※このページでは、使用フォント等によって、¥マークがバックスラッシュ(\)となって表示されていると思いますが、¥マークもバックスラッシュ(\)も同じです。

【エラー発生】"~" の中に " がある。\" にし忘れている

HTML関係のコードをPRINT "~~~"; の形式で記述するとよく発生します。ダブルコーテーション(")を出力する場合は「\"」にする必要があります。
だた面倒な場合は、シングルコーテーション (')で囲む方がミスが少ないです。
邪道ですが、HTMLのコードの場合はダブルコーテーション(")を使わないでも同じように動く場合が多いので、あえてダブルコーテーションを書かないという手もあります。

【想定以外の動作】変数展開に失敗している

稀にダブルコーテーション "~" で囲んで変数を中に入れると、変数展開時に間違って認識されてしまうことがあります。
そんなときは、$変数名 を ${変数名} と記載して、明確にすることで間違って認識されることがなくなります。複雑な展開をする場合は、書式化に対応した sprintf(・・・); を使用する方がいいでしょう。

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

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

【実行できないエラー】サーバ上のファイルの属性変更(実行属性への変更)を忘れていた

サーバにperlのファイルをアップロードした後に、属性変更をし忘れていると実行ファイルと識別されずに実行できません。perlプログラムを実行する場合、実行できるようにパーミッションを 705 や 707 に変更する必要があります。それを忘れると実行できません。利用しているレンタルサーバによって、パーミッションに指定があるので、確認しましょう。拡張子の指定があるときは、その拡張子にしておきます。たとえば .cgi にするなどが必要な場合があります。
(ホームページ運営会社によって異なります。さくらインターネットの場合は705に変更して、指定の拡張子にする必要があります)

【実行できないエラー】ファイルをFTPで「バイナリーモード」で転送していた

cgiプログラムをFTPで「バイナリーモード」で転送すると実行できない場合があります。その場合、「アスキーモード」にして転送します。
FFFTPでは、拡張子ごとに転送モードを設定する機能などもあります。

【エラー/想定以外の動作】漢字・2バイト文字が化ける(表示→侮ヲ)

実行時エラーではないですが、文字が化けるときがあります。
SHIFT-JISを使用している場合に発生します。
例えば「表示」という文字。「侮ヲ」になってしまいます。(ヲは半角)
print "表示";  → 「侮ヲ」
こんな時は
print "表\示";  → 「表示」
print '表示";  → 「表示」
として対処します。また、文字列を大文字にする関数もありますが、日本語処理に対応していない通常の関数 uc( ); などを使用すると、漢字が化けます。

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

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

  • 「予」 予定 ⇒ 予\定

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

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

  • 「欺」 詐欺 ⇒詐欺\

  • 「能」 芸能 ⇒芸能\

  • 「十」 十円 ⇒十\円

  • 「圭」 圭  ⇒圭\

  • 「申」 申込 ⇒申\込

  • 「蚕」 蚕  ⇒蚕\

  • 「暴」 暴行 ⇒暴\行

  • 「噂」 噂 ⇒ 噂\

  • 「―」 ― ⇒ ―\

  • 「構」 構造 ⇒構\造

  • 「貼」 貼付 ⇒貼\付

  • 「禄」 元禄 ⇒元禄\

  • 「拿」 拿捕 ⇒拿\捕

  • 「Ⅸ」 Ⅸ ⇒Ⅸ\

など・・・ Windowsなど SHIFT-JIS環境で作成している場合は、ダメ文字にご注意を。

【想定以外の動作】日本語が正しく検索されない

$temp_string の文字中に、$temp_keyword の文字を含んでいるかどうかのチェックする処理を実行しようとしても、$temp_keyword に SHIFT-JISの"ー" (のばす文字)や "表" や "暴" などの「ダメ文字」が入ると、文字列処理がうまくいかないのです。

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

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

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";
:

このコードを忘れないようにしましょう。(漢字コードの指定も間違えると化け化けるのでご注意を)

【想定以外の動作】同じ文字列変数のはずなのに イコールにならない(制御コードが入っている)

同じ文字列変数のはずなのに、なぜかイコールとならない・・・。そんな場合は制御コードが文字列変数に入ってしまっている可能性があります。

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


【想定以外の動作】文字列に意図しない空白が含まれている

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

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

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

この記事が気に入ったらサポートをしてみませんか?