blog20100901

2013/08/20 - プログラミング言語 Perl にまつわる etc. - Perl monger
参考 : perldoc, perldoc.jp, search.cpan.org, perldoc.perl.org ...
「 初めての Perl 第 6 版 」(オライリー・ジャパン発行 ISBN978-4-87311-567-2) 」
「 続・初めての Perl 改訂版 」(オライリー・ジャパン発行 ISBN4-87311-305-9) 」
「 Effective Perl 第 2 版 」(翔泳社発行 ISBN978-4-7981-3981-4) 」 ... etc,.

Perl Perl_0

Perl 配列の「 奇妙な空白 」 (0x2d)

Perl 配列の「 奇妙な空白 」 (0x2d)

Perl について、復習を兼ねて断片的な情報を掲載して行く連載その 0x2d 回。

Perl で、<STDIN> をリストコンテキストで使った場合で、配列に格納した入力行を表示したいのだけれど、出力の 2 行目以降の行頭に奇妙な空白が挿入されてしまうのはなぜなのでしょうか。


前回 (0x2c) のおさらい



まず、「 Perl リストコンテキストで「 STDIN 」を利用する (その 1) (0x2c) - 配列 - 奇妙な空白 」で確認した内容を振り返ります。

  + <STDIN> をリストコンテキストで使い複数行を一度に読み込む。
  + 読み込んだ行は配列に代入する。
  + 「 Ctrl + D 」をタイプして入力を終了する。
  + print 文で配列を表示する (ダブルクォート)。

  ? 2 行目以降の行頭に奇妙な空白が挿入される。

次のコードを利用しました。


print "Enter some lines, then press Ctrl + D:\n";
@line = ;

print "@line";


次の文字列を入力しました。

Hello, Perl.
I enter strings from <STDIN>.
With what results ?


すると、次の様に奇妙な空白を含む表示になりました。

Hello, Perl.
  I enter strings from <STDIN>.
  With what results ?


次の様に、print 文の配列のダブルクォーテーションをはずしてみると、


print @line;


次の様に奇妙な空白がなくなりました。

Hello, Perl.
I enter strings from .
With what results ?


このことから、 print 文で配列を表示する際のスタイルに原因があることがわかりました。

配列要素の出力の差異



「 奇妙な空白 」の原因を突き止めるために、まずは、print 文の配列変数の出力について、単純な例をもって確認してみます。


@eva = qw/ rei shinji asuka /;

print "Quoted:\n@eva\n";

print "Not Quoted:\n", @eva, "\n";


3 行目はクォートした配列変数を表示します。

5 行目はクォートしない配列変数を表示します。ここでは print 関数に「 , (カンマ) 」を使ったリストデータをを渡しています。2 番目のデータにあたる配列変数はクォートしていません。

print 文で「 , 」の代わりに「 . (ピリオド) 」を使うと、それはスカラコンテキストになるらしく、配列の要素数が表示されます。

出力結果を見てみましょう。

Quoted:
rei shinji asuka
Not Quoted:
reishinjiasuka


「 Quoted 」の表示では、配列変数の要素の値がスペースで区切られていますが、「 Not Quoted 」の表示では、要素間の区切りがありません。


Perl 配列を変数展開する際の注意点 (0x26) - 配列変数の変数展開 」で少し触れましたが、配列変数を変数展開するためにダブルクォートで囲んだ場合、特殊な変数「 $" 」で設定された値が区切り文字として採用されます。

「 $" 」には標準で空白が設定されているため、これが表示の差異となっているわけです。

奇妙な空白の正体



標準では、この「 $" 」に設定された値が空白文字になっているため、「 Quoted 」で表示される配列をダブルクォートで表示する場合、各要素は空白文字で区切られることになります。

これを踏まえて、次のコードを振り返りましょう。


print "Enter some lines, then press Ctrl + D:\n";
@line = ;

print "@line";


2 行目の配列変数が、仮に 3 行のデータを受け取ったとすると、その内部は次の様になっています。

文字列\n(空白)文字列\n(空白)文字列\n


「 \n 」は標準入力でキーボードから入力された改行文字です。「 (空白) 」は「 $" 」で標準設定された区切り文字です。

これを 4 行目で変数展開するので、結果はこの様になるわけです。

文字列\n
(空白)文字列\n
(空白)文字列\n


つまり、こうですね。

Hello, Perl.
  I enter strings from .
  With what results ?


ということです。

0x2d -> 0x2e へ



初めての Perl 第 6 版 - 5.4 標準出力への出力 (P.105) 」によると、Perl のメーリングリストやフォーラムでは、今回説明した奇妙な空白についての問い合わせが頻繁に提出されるそうです。

著者曰く、「 1 - 2 週間ごとに 」とのことなので、それは「 やれやれだぜ 」の心境にならざるを得ないでしょう。

次回は、「 それは改行だ。改行が問題なんだ。だから取り除け。そしてコントロールしろ。」をお届けします。

参考情報は以下の書籍を中心に Wikipedia および各 Web サイト。それと詳しい先輩。

参考 :「Randal L. Schwartz, brian d foy, Tom Phoenix 共著 近藤 嘉雪 訳「初めての Perl 第 6 版」(オライリー・ジャパン発行 ISBN978-4-87311-567-2)」

次回 (0x2e) へ続く。

過去記事 RSS










同じカテゴリー(Perl)の記事
 Perl mp2 翻訳 Web コンテンツ圧縮の FAQ (d228) (2023-10-11 23:49)
 Perl mp2 翻訳 既知のブラウザのバグの回避策をいくつか (d227) (2023-05-26 15:41)
 Perl mp2 翻訳 Perl と Apache でのキュートなトリック (d226) (2023-05-19 17:05)
 Perl mp2 翻訳 テンプレートシステムの選択 (d225) (2022-08-15 22:23)
 Perl mp2 翻訳 大規模 E コマースサイトの構築 (d224) (2022-06-15 20:43)
 Perl mp2 翻訳 チュートリアル (d223) (2022-06-15 20:42)
上の画像に書かれている文字を入力して下さい
 
<ご注意>
書き込まれた内容は公開され、ブログの持ち主だけが削除できます。

Llama
リャマ
TI-DA
てぃーだブログ
プロフィール
セラ (perlackline)
セラ (perlackline)
QRコード
QRCODE
オーナーへメッセージ

PAGE TOP ▲