お読みになっている第3回のカテゴリーは「かんたんPerl補遺」です。補遺はホイと読みます。「ラブレボリューション21、ホイ」という歌もありましたが、補遺というのは書ききれなかったことを、後から付け足すことです。
『かんたんPerl』には、紙数の制限(ページ数と判型の制限)によって、書いたり書かなかったりしたことがあります。と、書くと「不完全な本なんですか!」と怒られるかもしれませんが、聖書や六法全書を初め、この世に必要なことをすべてもらさず書いた本はありません。『かんたんPerl』は初学者のみなさんが楽しく学び、実作業をバリバリこなすために必要不可欠なことを、厳選して書いてあります。削る方も辛かったんだよー!
 ということで、本ブログの「かんたんPerl補遺」カテゴリーには、書かれた部分に比べるとどちらかというと、トリビアルで、知らなくてもそんなに困らないけど、『かんたんPerl』を読んで病膏肓に入って、Perlのことなら何でも知らないと気が済まない方のために、本では割愛した部分を粛々と埋めていこうと思います。
 逆に、本にすでに書いてある部分については、説明を割愛します。つまり、ので、本を読んでいない方は買って読んでください、と、言いたいところはヤマヤマなんですが、それだとあんまりゴーマンなので、せいぜいこのブログだけでも完結した説明を努めます。どうぞよろしくお読みください。
 
 Perlで文字列リテラルを書くとき、『かんたんPerl』では基本的に二重引用符を使ってきました。以下のコードを見てください。

#! /usr/local/bin/perl
# testDoubleQuote.pl -- 二重引用符のテスト

use strict;
use warnings;
use 5.010;
use utf8;
binmode STDOUT, ":encoding(UTF-8)";

say "こんにちはー";

 実行します。

[sample]$ ./testDoubleQuote.pl
こんにちはー

 ここで、"こんにちはー"は文字列です。これだけだと、二重引用符を使おうが、一重引用符を使おうが一緒です。

#! /usr/local/bin/perl
# testSingleQuote.pl -- 一重引用符のテスト

use strict;
use warnings;
use 5.010;
use utf8;
binmode STDOUT, ":encoding(UTF-8)";

say 'こんにちはー';

 実行します。

[sample]$ ./testSingleQuote.pl
こんにちはー

 特に変更はありませんでしたね。このブログは基本的にこんな感じで進行するので馴染んでください。

 さて、二重引用符にあって一重引用符にない機能の1つは、バックスラッシュをエスケープ文字列の始まりとして扱う時です。バックスラッシュはASCII文字コード系で0x5Cにあたる字で、字形としては\の半角になります。Windowsをお使いの方はフォントによっては¥の半角に見えるかもしれませんが、本ブログとしての呼び名はバックスラッシュに統一します。
 次のコードを見てください。

#! /usr/local/bin/perl
# testQuotes.pl -- 引用符のテスト

use strict;
use warnings;
use 5.010;
use utf8;
binmode STDOUT, ":encoding(UTF-8)";

say "こんにちはー。まず二重引用符について研究します。";
say "バックスラッシュ1つだけ書いてみました【\】";
say "バックスラッシュ1つに続いてnを書いてみました【\n】";
say "バックスラッシュ2つに続いてnを書いてみました【\\n】";

say "---";

say 'では次に、一重引用符について研究します。';
say 'バックスラッシュ1つだけ書いてみました【\】';
say 'バックスラッシュ1つに続いてnを書いてみました【\n】';
say 'バックスラッシュ2つに続いてnを書いてみました【\\n】';

 二重引用符と、一重引用符の中で、「\」、「\n」、「\\n」がそれぞれどのように見えるかテストしています。
 では実行。

[sample]$ ./testQuotes.pl
こんにちはー。まず二重引用符について研究します。
バックスラッシュ1つだけ書いてみました【】
バックスラッシュ1つに続いてnを書いてみました【

バックスラッシュ2つに続いてnを書いてみました【\n】
---
では次に、一重引用符について研究します。
バックスラッシュ1つだけ書いてみました【\】
バックスラッシュ1つに続いてnを書いてみました【\n】
バックスラッシュ2つに続いてnを書いてみました【\n】

 動作が違いますね。

 二重引用符の方は、『かんたんPerl』でさんざん研究した動作です。
 バックスラッシュ1つは、後ろにn、tなどのエスケープ文字として意味のある字が来たらエスケープ文字になり、それ以外の場合は消失します。
 「【\】」では、「\】」というエスケープ文字はありませんから「\」が消失し、「【】」となりました。
 「【\n】」では、「\n」が改行(Newline)という意味のエスケープ文字となり、「【」と「】」の間に改行が入りました。
 「【\\n】」では、「\\」が1つの「\」になるので「\n」では改行が起きず、「【\n】」となりました。

 一重引用符ではバックスラッシュはエスケープ文字を生成するという特別な意味がありませんので、「【\】」も「【\n】」も書いたまま表示されました。
 ただし!「\\n」だけは要注意で、\\を\にするという機能だけは残っています。これはなぜかというと、一重引用符自体を一重引用符の中で使うためです。

#! /usr/local/bin/perl
# testSingleQuote2.pl -- 一重引用符のテスト

use strict;
use warnings;
use 5.010;
use utf8;
binmode STDOUT, ":encoding(UTF-8)";

say '一重引用符とは【'】のことです。';

というコードを実行すると、エラーになります。

[sample]$ ./testSingleQuote2.pl
Wide character in print at ./testSingleQuote2.pl line 10.
Unrecognized character \x{ff1c}; marked by <-- HERE after '一重引用符とは【'<-- HERE near column 15 at ./testSingleQuote2.pl line 10.

 これは当然で、

say '一重引用符とは【'】のことです。';

までで1つの一重引用符のペアが完成してしまうので、後ろに「】のことです。'」というむき出しの文字列が書かれてしまってエラーになっています。
 ではどうするかというと、一重引用符をバックスラッシュでエスケープします。

#! /usr/local/bin/perl
# testSingleQuote3.pl -- 一重引用符のテスト

use strict;
use warnings;
use 5.010;
use utf8;
binmode STDOUT, ":encoding(UTF-8)";

say '一重引用符とは【\'】のことです。';

とすれば、

[sample]$ ./testSingleQuote3.pl
一重引用符とは【'】のことです。

と正しく動作します。

 一重引用符になくて二重引用符にあるもののもう1つは変数展開です。

#! /usr/local/bin/perl
# testQuotes2.pl -- 引用符のテスト

use strict;
use warnings;
use 5.010;
use utf8;
binmode STDOUT, ":encoding(UTF-8)";

my $var = 10;

say "Let's test double quotes.";
say "My today's allowance is $var dollars.";

say "---";

say 'Next, let\'s test single quotes.';
say 'My today\'s allowance is $var dollars.'

 急に英語になりましたが、今日のお小遣い(allowance)について述べています。実行します。

[sample]$ ./testQuotes2.pl
Let's test double quotes.
My today's allowance is 10 dollars.
---
Next, let's test single quotes.
My today's allowance is $var dollars.

 まず「Let's」と「today's」のアポストロフィが一重引用符版では\'とバックスラッシュでエスケープされています。これはさっきの話題ですね。
 次に変数$varです。
 二重引用符の場合は変数$varが値「10」で置換され、おいらの今日のお小遣いは10ドルです、という意味の英文になっています。
 いっぽう一重引用符の場合は$varという文字列が変数としては認識されず、そのまま出てしまっているのであまり意味がありません。

 ところが、二重引用符の方が困ることがあって、$という文字を引用符の中でそのまま使いたい時です。

#! /usr/local/bin/perl
# testQuotes3.pl -- 引用符のテスト

use strict;
use warnings;
use 5.010;
use utf8;
binmode STDOUT, ":encoding(UTF-8)";

say "Let's test double quotes.";
say "My today's allowance is $10.";

say "---";

say 'Next, let\'s test single quotes.';
say 'My today\'s allowance is $10.'

 今回は変数$varを使わず、$10(10ドル)という金額を文字列リテラルで書いてみましたが、これがバグになります。

[sample]$ ./testQuotes3.pl
Let's test double quotes.
Use of uninitialized value $10 in concatenation (.) or string at ./testQuotes3.pl line 11.
My today's allowance is .
---
Next, let's test single quotes.
My today's allowance is $10.

 一重引用符の方は$10という文字列が正しく表示されました。
 いっぽう二重引用符の方は「$10という未定義値を表示しようとした」と警告が出て、「My today's allowance is .」のように$10という文字列が削除されてしまいました。二重引用符を使ったぐらいで、お小遣いが無になるなんてあんまりですね。これは$10を変数として解釈したが、未定義値のために警告が出たという状態です。
 この場合は、二重引用符の方をバックスラッシュでエスケープし、\$10とします。

#! /usr/local/bin/perl
# testQuotes4.pl -- 引用符のテスト

use strict;
use warnings;
use 5.010;
use utf8;
binmode STDOUT, ":encoding(UTF-8)";

say "Let's test double quotes.";
say "My today's allowance is \$10.";

say "---";

say 'Next, let\'s test single quotes.';
say 'My today\'s allowance is $10.'

 さあどうだ。

[sample]$ ./testQuotes4.pl
Let's test double quotes.
My today's allowance is $10.
---
Next, let's test single quotes.
My today's allowance is $10.

 ちなみに、$tenという、あまり英語としてはあるかどうか分からない書き方で10ドルを表現するとします。
 で、しょうこりもなく二重引用符の中で$を\でエスケープするということを忘れたとします。

#! /usr/local/bin/perl
# testQuotes5.pl -- 引用符のテスト

use strict;
use warnings;
use 5.010;
use utf8;
binmode STDOUT, ":encoding(UTF-8)";

say "Let's test double quotes.";
say "My today's allowance is $ten.";

say "---";

say 'Next, let\'s test single quotes.';
say 'My today\'s allowance is $ten.'

さっきと違うパターンのエラーになります。

[sample]$ ./testQuotes5.pl
Global symbol "$ten" requires explicit package name at ./testQuotes5.pl line 11.
Execution of ./testQuotes5.pl aborted due to compilation errors.

 $tenという変数がパッケージ名に属していない、こんなプログラムはコンパイルに値しないから実行を中止すると言っています。
 厳しいな! 実は$10の方の「$10には未定義値が入っています」というのはwarningsモジュールが発生した警告で、プログラムの方は$10が空文字列になるだけでプログラムの実行は完走しています。一方、$tenの方は「$tenという変数が定義されていないのでコンパイル自体行わない!」と怒りまくっていて、これはstrictモジュールの方のエラーです。
 なぜでしょうか。これは2015-01-18に起票予定のブログ記事「Opus 8」までの宿題にしますので、みなさん各自考えてください。ちなみに『かんたんPerl』をお買い上げの方は第10章のp.458まで読めば分かります。

 さて、長々と書いてきましたが、一重引用符と二重引用符のまとめは以下のようになります。

【二重引用符】
  • "\n"と書くと改行になる
  • 「\n」と書きたい場合は"\\n"と書く
  • "$var"と書くと変数の値になる
  • 「$var」と書きたい場合は"\$var"と書く
  • "\こんにちは"と書くと「こんにちは」になる
  • 「\こんにちは」と書きたい場合は"\\こんにちは"と書く
  • "'あはは'"と書くと「'あはは'」になる
【一重引用符】
  • '\n'と書くと「\n」になる
  • '$var'と書くと「$var」になる
  • '\こんにちは'と書くと「\こんにちは」になる
  • '\\こんにちは'と書いても「\こんにちは」になる
  • 「\\こんにちは」と書きたい場合は「\\\こんにちは」と書く
  • ''あはは''と書くと空文字列の間に裸のワード「あはは」が入った状態になって怒られる
  • 「'あはは'」と書きたいときは'\'あはは\''と書く
 いかがでしょうか。ていうか、こんなのわざわざ丸暗記する必要なくて、ふだんは無理しないで二重引用符を使って、たまに\や$を書きたいときは\でエスケープすればいいと思います。とくに「'あはは'」と書きたいときは'\'あはは\''などと無理矢理一重引用符を使わず、素直に二重引用符で"'あはは'"と書いたほうがいいでしょう。
 
 一重引用符を使った方が絶対にラクチンな場合が1つあって、それはWindowsのパス名を直接書く時です。
 「C:\Users\query1000\Perl\bin\perl」というパス名を文字列リテラルに入れるとき、二重引用符だとバックスラッシュを全部エスケープしないといけませんから、もしこの世に一重引用符がなかったら"C:\\Users\\query1000\\Perl\\bin\\perl"と書かないといけないところです。ゾワゾワっとしますね。
 これは一重引用符を使えば'C:\Users\query1000\Perl\bin\perl'と書けてラクチンです。