Perlのエラーメッセージのコーナー。今回は
これは
(S:主語) / = スラッシュは
(V:動詞) must be = でなければならない
(C:補語) followed by a, A, or Z = a、A、あるいはZの前
ということで、「スラッシュ/は、a、A、あるいはZの前でなければならない」と書かれている。
英語は比較的シンプルだ。
でも、どういう文脈かはメッセージだけでは分からない。
/ must be followed by a, A, or Zである。
これは
(S:主語) / = スラッシュは
(V:動詞) must be = でなければならない
(C:補語) followed by a, A, or Z = a、A、あるいはZの前
ということで、「スラッシュ/は、a、A、あるいはZの前でなければならない」と書かれている。
英語は比較的シンプルだ。
でも、どういう文脈かはメッセージだけでは分からない。
ラクダ本を見てみると、以下のように書いている。
では、長さ指定付き文字列とはなんだろうか。
以下のプログラム
packのテンプレートに「A4/A*」と書いている。
スラッシュの前のA4は長さを表す部分で、4バイトのバイトストリング(スペースを詰める)になっている。
スラッシュの後のA*は文字列本体で、長さが不定のバイトストリングになっている。
最初に
文字列「abcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJ」は100バイトなので、先頭に「100 」となっているのだ。
(余った1バイトにスペースが入っている。)
で、同じテンプレート「A4/A*」を使って$packedをunpackすることによって、
unpackの場合は「A4/A」だけで良い。
末尾に*を書いても無視される。
ただし、この場合はpackのテンプレートをそのまま写した方が分かりやすいので、unpackにも不要な*を追加した。
さて、このスラッシュを使って「長さ/文字列」を書くやり方は、a(バイトストリング、ヌル文字を詰める)、A(バイトストリング、空白文字を詰める)、Z(ヌルで終了する文字列)のいずれかでなければならないとなる。
ちょっといたずらして、unpackのテンプレートを「A4/H*」としてみる。
この場合は、長さが100ニブルの(50バイトぶんの)16進数に「abcde・・・」を変換したものになっている。
ということで、このエラーメッセージは出せなかった!
Perlが最近バージョンアップして、この診断メッセージが出なくなったのではないだろうか。
(たしかにどんな形にでも変換出来た方が便利に見える。)
perldeltaを渉猟して、いつのバージョンで変わったのか調べてみたのだが、すぐには分からなかった。
スミマセン。
unpackのテンプレートで長さ指定付き文字列を指定する場合、/の後ろには、アンパックする文字列の種類を示すa、A、Zのどれかを置かなければならない。ということで、unpack関数の使い方に関するメッセージである。
では、長さ指定付き文字列とはなんだろうか。
以下のプログラム
#! /usr/bin/perlを実行するとこうなる。
# packUnpack.pl
use strict;
use warnings;
use utf8;
use 5.10.0;
my $packed = pack 'A4/A*',
"abcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJ";
say "packed:", $packed;
my $unpacked = unpack 'A4/A*', $packed;
say "unpacked:", $unpacked;
$ packUnpack.pl上のコードは
packed:100␣abcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJ
unpacked:abcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJ
abcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJという長さが不明な文字列をpack/unpackするものである。
packのテンプレートに「A4/A*」と書いている。
スラッシュの前のA4は長さを表す部分で、4バイトのバイトストリング(スペースを詰める)になっている。
スラッシュの後のA*は文字列本体で、長さが不定のバイトストリングになっている。
最初に
my $packed = pack 'A4/A*',を実行することによって、$packedには
"abcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJ";
100␣abcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJが入る。(␣は実際には空白)
文字列「abcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJ」は100バイトなので、先頭に「100 」となっているのだ。
(余った1バイトにスペースが入っている。)
で、同じテンプレート「A4/A*」を使って$packedをunpackすることによって、
abcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJが得られる。
unpackの場合は「A4/A」だけで良い。
末尾に*を書いても無視される。
ただし、この場合はpackのテンプレートをそのまま写した方が分かりやすいので、unpackにも不要な*を追加した。
さて、このスラッシュを使って「長さ/文字列」を書くやり方は、a(バイトストリング、ヌル文字を詰める)、A(バイトストリング、空白文字を詰める)、Z(ヌルで終了する文字列)のいずれかでなければならないとなる。
ちょっといたずらして、unpackのテンプレートを「A4/H*」としてみる。
my $unpacked = unpack 'A4/H*', $packed;実行してみる。
$ packUnpack.plあれ、ちゃんと出来ている。
packed:100␣abcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJabcdefghijABCDEFGHIJ
unpacked:6162636465666768696a4142434445464748494a6162636465666768696a4142434445464748494a6162636465666768696a
この場合は、長さが100ニブルの(50バイトぶんの)16進数に「abcde・・・」を変換したものになっている。
ということで、このエラーメッセージは出せなかった!
Perlが最近バージョンアップして、この診断メッセージが出なくなったのではないだろうか。
(たしかにどんな形にでも変換出来た方が便利に見える。)
perldeltaを渉猟して、いつのバージョンで変わったのか調べてみたのだが、すぐには分からなかった。
スミマセン。