argra****@users*****
argra****@users*****
2007年 9月 9日 (日) 03:35:01 JST
Index: docs/perl/5.8.8/perlpacktut.pod diff -u docs/perl/5.8.8/perlpacktut.pod:1.2 docs/perl/5.8.8/perlpacktut.pod:1.3 --- docs/perl/5.8.8/perlpacktut.pod:1.2 Wed Aug 29 18:18:53 2007 +++ docs/perl/5.8.8/perlpacktut.pod Sun Sep 9 03:35:00 2007 @@ -61,6 +61,15 @@ =end original +In Perl, you just can't access memory at random, but the structural and +representational conversion provided by C<pack> and C<unpack> is an +excellent alternative. The C<pack> function converts values to a byte +sequence containing representations according to a given specification, +the so-called "template" argument. C<unpack> is the reverse process, +deriving some values from the contents of a string of bytes. (Be cautioned, +however, that not all that has been packed together can be neatly unpacked - +a very common experience as seasoned travellers are likely to confirm.) +(TBT) =begin original @@ -76,6 +85,16 @@ =end original +Why, you may ask, would you need a chunk of memory containing some values +in binary representation? One good reason is input and output accessing +some file, a device, or a network connection, whereby this binary +representation is either forced on you or will give you some benefit +in processing. Another cause is passing data to some system call that +is not available as a Perl function: C<syscall> requires you to provide +parameters stored in the way it happens in a C program. Even text processing +(as shown in the next section) may be simplified with judicious usage +of these two functions. +(TBT) =begin original @@ -90,6 +109,15 @@ =end original +To see how (un)packing works, we'll start with a simple template +code where the conversion is in low gear: between the contents of a byte +sequence and a string of hexadecimal digits. Let's use C<unpack>, since +this is likely to remind you of a dump program, or some desperate last +message unfortunate programs are wont to throw at you before they expire +into the wild blue yonder. Assuming that the variable C<$mem> holds a +sequence of bytes that we'd like to inspect without assuming anything +about its meaning, we can write +(TBT) my( $hex ) = unpack( 'H*', $mem ); print "$hex\n"; @@ -101,6 +129,9 @@ =end original +whereupon we might see something like this, with each pair of hex digits +corresponding to a byte: +(TBT) 41204d414e204120504c414e20412043414e414c2050414e414d41 @@ -122,6 +153,20 @@ =end original +What was in this chunk of memory? Numbers, characters, or a mixture of +both? Assuming that we're on a computer where ASCII (or some similar) +encoding is used: hexadecimal values in the range C<0x40> - C<0x5A> +indicate an uppercase letter, and C<0x20> encodes a space. So we might +assume it is a piece of text, which some are able to read like a tabloid; +but others will have to get hold of an ASCII table and relive that +firstgrader feeling. Not caring too much about which way to read this, +we note that C<unpack> with the template code C<H> converts the contents +of a sequence of bytes into the customary hexadecimal notation. Since +"a sequence of" is a pretty vague indication of quantity, C<H> has been +defined to convert just a single hexadecimal digit unless it is followed +by a repeat count. An asterisk for the repeat count means to use whatever +remains. +(TBT) =begin original @@ -130,6 +175,8 @@ =end original +逆操作 - 16 進数の文字列からバイトの内容に pack する - は簡単に書けます。 +例えば: my $s = pack( 'H2' x 10, map { "3$_" } ( 0..9 ) ); print "$s\n"; @@ -142,7 +189,11 @@ =end original - +16 進で 2 桁の数値を示す文字列 10 個からなるリストを C<pack> に +渡しているので、pack テンプレートは 10 個の pack コードを含んでいる +必要があります。 +これが ASCII 文字コードのコンピュータで実行されると、 C<0123456789> を +表示されます。 =head1 Packing Text @@ -351,7 +402,6 @@ =back - =begin original Hence, putting it all together: @@ -1396,6 +1446,9 @@ =end original +遠くに微妙な罠が顔を覗かせています: (変数 C<$sm> に入っている) +ショートメッセージの後にフィールドを追加すると、pack は問題ありませんが、 +ネイティブに unpack 出来なくなります。 # pack a message my $msg = pack( 'Z*Z*CA*C', $src, $dst, length( $sm ), $sm, $prio ); @@ -1412,6 +1465,10 @@ =end original +pack コード C<A*> は残り全てのコードを読み込んでしまい、C<$prio> が +未定義のままになってしまうのです! +がっかりして士気をくじかれる前に: Perl はこのようなトリックに対しても +切り札を持っています; もう少し袖をまくってください。 # pack a message: ASCIIZ, ASCIIZ, length/string, byte my $msg = pack( 'Z* Z* C/A* C', $src, $dst, $sm, $prio ); @@ -1793,6 +1850,9 @@ =end original +Where's the catch? Padding is neither required before the first field C<count>, +nor between this and the next field C<glyph>, so why can't we simply pack +like this: # something goes wrong here: pack( 's!a' x @buffer, @@ -1808,6 +1868,11 @@ =end original +This packs C<3*@buffer> bytes, but it turns out that the size of +C<buffer_t> is four times C<BUFLEN>! The moral of the story is that +the required alignment of a structure or array is propagated to the +next higher level where we have to consider padding I<at the end> +of each component as well. Thus the correct template is: pack( 's!ax' x @buffer, map{ ( $_->{count}, $_->{glyph} ) } @buffer ); @@ -2039,6 +2104,9 @@ =end original +Do not use C<pack> with C<p> or C<P> to obtain the address of variable +that's bound to go out of scope (and thereby freeing its memory) before you +are done with using the memory at that address. =item * @@ -2050,6 +2118,9 @@ =end original +Be very careful with Perl operations that change the value of the +variable. Appending something to the variable, for instance, might require +reallocation of its storage, leaving you with a pointer into no-man's land. =item * @@ -2062,6 +2133,10 @@ =end original +Don't think that you can get the address of a Perl variable +when it is stored as an integer or double number! C<pack('P', $x)> will +force the variable's internal representation to string, just as if you +had written something like C<$x .= ''>. =back @@ -2072,8 +2147,8 @@ =end original - - +It's safe, however, to P- or p-pack a string literal, because Perl simply +allocates an anonymous variable. =head1 Pack Recipes Index: docs/perl/5.8.8/perlref.pod diff -u docs/perl/5.8.8/perlref.pod:1.1 docs/perl/5.8.8/perlref.pod:1.2 --- docs/perl/5.8.8/perlref.pod:1.1 Thu Aug 30 15:58:16 2007 +++ docs/perl/5.8.8/perlref.pod Sun Sep 9 03:35:00 2007 @@ -137,6 +137,8 @@ =head2 Making References X<reference, creation> X<referencing> +(リファレンスを作る) + =begin original References can be created in several ways. @@ -204,7 +206,7 @@ =end original -名前の無い配列へのリファレンスは、ブラケットを使って作ることができます: +名前の無い配列へのリファレンスは、大かっこを使って作ることができます: $arrayref = [1, 2, ['a', 'b', 'c']]; @@ -617,11 +619,9 @@ その不利な点は新しいハンドルをあなたのために作り出すことはしないと いうことです。 有利な点は、型グロブの代入を使うよりも気をつかう必要があまりないということです。 -(It still conflates file -and directory handles, though.) However, if you assign the incoming -value to a scalar instead of a typeglob as we do in the examples -below, there's no risk of that happening. -(TBT) +(しかし、これはまだファイルハンドルとディレクトリハンドルを融合します。) +しかし、もし以下の例で行っているように、値を型グロブではなくスカラに +代入すると、起きることに対するリスクはありません。 splutter(*STDOUT); # pass the whole glob splutter(*STDOUT{IO}); # pass both file and dir handles @@ -644,6 +644,8 @@ =head2 Using References X<reference, use> X<dereferencing> X<dereference> +(リファレンスを使う) + =begin original That's it for creating references. By now you're probably dying to @@ -904,6 +906,12 @@ =end original +Using a string or number as a reference produces a symbolic reference, +as explained above. Using a reference as a number produces an +integer representing its storage location in memory. The only +useful thing to be done with this is to compare two references +numerically to see whether they refer to the same location. +X<reference, numeric context> (TBT) if ($ref1 == $ref2) { # cheap numeric compare of references @@ -921,6 +929,12 @@ =end original +Using a reference as a string produces both its referent's type, +including any package blessing as described in L<perlobj>, as well +as the numeric address expressed in hex. The ref() operator returns +just the type of thing the reference is pointing to, without the +address. See L<perlfunc/ref> for details and examples of its use. +X<reference, string context> (TBT) =begin original @@ -984,6 +998,8 @@ X<reference, symbolic> X<reference, soft> X<symbolic reference> X<soft reference> +(シンボリックリファレンス) + =begin original We said that references spring into existence as necessary if they are @@ -1086,6 +1102,8 @@ =head2 Not-so-symbolic references +(あまりシンボリックではないリファレンス) + =begin original A new feature contributing to readability in perl version 5.001 is that the @@ -1212,6 +1230,8 @@ =head2 Pseudo-hashes: Using an array as a hash X<pseudo-hash> X<pseudo hash> X<pseudohash> +(擬似ハッシュ: 配列をハッシュとして使う) + =begin original B<WARNING>: This section describes an experimental feature. Details may @@ -1220,8 +1240,7 @@ =end original B<警告>: このセクションは実験的機能を説明しています。 -将来のバージョンにおいて、 -細かな点は予告なしに変更される可能性があります。 +将来のバージョンにおいて、細かな点は予告なしに変更される可能性があります。 =begin original @@ -1234,7 +1253,12 @@ =end original -(TBT) +B<注意>: 現在のユーザー見える形の擬似ハッシュの実装(配列の最初の要素を +奇妙な形で使うもの)は Perl 5.8.0 から非推奨となりました; Perl 5.8.10 からは +取り除かれて、この機能は別の方法で実装される予定です。 +現在のインターフェースは醜いだけでなく、現在の実装は通常の配列とハッシュの +利用をかなり目立つ形で遅くしています。 +"fields" プラグマインターフェースは利用可能なまま残ります。 =begin original @@ -1313,7 +1337,12 @@ =end original -(TBT) +擬似ハッシュでキーの存在をチェックする方法は 2 つあります。 +1 つめは exists() を使うことです。 +このチェックは、指定されたフィールドに値がセットされたことがあるかどうかが +わかります。 +これはこの意味で通常のハッシュの振る舞いと一致します。 +例えば: use fields; $phash = fields::phash([qw(foo bar pants)], ['FOO']); @@ -1331,6 +1360,9 @@ =end original +2 つめは、最初の配列要素にあるハッシュリファレンスに exists() を +使うことです。 +これは、キーが擬似ハッシュの有効なフィールドであるかをチェックします。 print exists $phash->[0]{bar}; # true, 'bar' is a valid field print exists $phash->[0]{shoes};# false, 'shoes' can't be used @@ -1343,6 +1375,9 @@ =end original +擬似ハッシュの要素に対する delete() はキーそのものではなく、キーに対応する +値だけを削除します。 +キーを削除するには、最初のハッシュ要素から明示的に削除する必要があります。 print delete $phash->{foo}; # prints $phash->[1], "FOO" print exists $phash->{foo}; # false @@ -1354,6 +1389,8 @@ X<scope, lexical> X<closure> X<lexical> X<lexical scope> X<subroutine, nested> X<sub, nested> X<subroutine, local> X<sub, local> +(関数テンプレート) + =begin original As explained above, an anonymous function with access to the lexical @@ -1467,19 +1504,19 @@ =end original 型を変更するようなレキシカル変数に対するアクセス -- -たとえば先の例のC<for>ループのようなもの、は +たとえば先の例の C<for> ループのようなもの、は クロージャに置いてのみ動作し、一般的なサブルーチンでは動作しません。 -一般的なケースでは、名前付きサブルーチンは -適切にネストすることはなく、(ネストするものが)無名関数であっても同じです。 -Thus is because named subroutines are created (and capture any -outer lexicals) only once at compile time, whereas anonymous subroutines -get to capture each time you execute the 'sub' operator. +一般的なケースでは、名前付きサブルーチンは適切にネストすることはなく、 +(ネストするものが)無名関数であっても同じです。 +これは、名前つきのサブルーチンはコンパイル時に一度だけ作成される +(そして外側のレキシカルに捕捉される)のに対し、無名サブルーチンは +'sub' 演算子が実行される毎に捕捉されるからです。 他のプログラミング言語にあるような、固有のプライベート変数を持った -ネストしたサブルーチンを使いたいのであれば、 -Perlではちょっと手間がかかります。直感的にこうだと思うような -コーディングは、不可思議な警告``will not stay shared''となるでしょう。 +ネストしたサブルーチンを使いたいのであれば、Perlではちょっと +手間がかかります。 +直感的にこうだと思うようなコーディングは、不可思議な警告 +``will not stay shared''となるでしょう。 例を挙げると、以下の例はうまく動作しません: -(TBT) sub outer { my $x = $_[0] + 35; @@ -1586,9 +1623,8 @@ =end original ドキュメントの他に、ソースコードもためになります。 -幾つかのリファレンスを使っている病理学的な -サンプル(pathological examples)は Perl のソースディレクトリにある -F<t/op/ref.t> というテストに見つけ出すことができます。 +幾つかのリファレンスを使っている病理学的なサンプルは Perl の +ソースディレクトリにある F<t/op/ref.t> という退行テストにあります。 =begin original @@ -1599,7 +1635,7 @@ =end original 複雑なデータ構造を生成するためのリファレンスの使い方は -L<perldsc>、 L<perllol> を参照してください。 +L<perldsc> と L<perllol> を参照してください。 オブジェクトを生成するためのリファレンスの使い方は L<perltoot>、L<perlobj>、L<perlbot> を参照してください。 Index: docs/perl/5.8.8/perlsyn.pod diff -u docs/perl/5.8.8/perlsyn.pod:1.1 docs/perl/5.8.8/perlsyn.pod:1.2 --- docs/perl/5.8.8/perlsyn.pod:1.1 Thu Aug 30 15:58:16 2007 +++ docs/perl/5.8.8/perlsyn.pod Sun Sep 9 03:35:00 2007 @@ -390,7 +390,7 @@ L<perlfunc/do> を参照してください。 後述するループの制御文は、修飾子がループラベルを取らないために -この構造文では B<動作しない> ということにも注意してください。 +この構造文では I<動作しない> ということにも注意してください。 申し訳ない。 こういった場合に対処するのに別のブロックを内側に入れたり(C<next> の場合)、 別のブロックで囲む(C<last> の場合)という方法が常に使えます。 @@ -498,7 +498,7 @@ しかし注意して欲しいのは、C や Pascal とは異なり、ブロックを取るように 定義されていて文を取るではないということです。 -つまり、中かっこは B<必要なもの> で、曖昧な文が許されないということです。 +つまり、中かっこは I<必要なもの> で、曖昧な文が許されないということです。 中かっこなしの条件文を使いたいのであれば、いくつかのやり方があります。 以下にその例を示します。 @@ -609,7 +609,7 @@ C<redo> コマンドは、条件の再評価をすることなしにループブロックの 再実行を行います。 -C<continue> ブロックがあっても、それは B<実行されません>。 +C<continue> ブロックがあっても、それは I<実行されません>。 このコマンドは通常、プログラムに対する入力に関してプログラム自身を だましたいといったときに使われます。 Index: docs/perl/5.8.8/perltie.pod diff -u docs/perl/5.8.8/perltie.pod:1.1 docs/perl/5.8.8/perltie.pod:1.2 --- docs/perl/5.8.8/perltie.pod:1.1 Thu Sep 6 20:24:39 2007 +++ docs/perl/5.8.8/perltie.pod Sun Sep 9 03:35:00 2007 @@ -2276,7 +2276,7 @@ 問題は、GDBM と Berkeley DB はサイズに制限があり、それを超えることが できないということで、また、ディスク上にあるものを参照する方法についても 問題があります。 -不完全ながらもこれを解決している一つの実験的なモジュールに、 +これを解決しようとしている実験的なモジュールの一つに、 DBM::Deep というものがあります。 ソースコードは L<perlmodlib> にあるように、 あなたのお近くの CPAN サイトを確かめてください。