=head1 NAME 名前 B::Deparse - Perl compiler backend to produce perl code B::Deparse - perl コードを生成するPerlコンパイラバックエンド =head1 SYNOPSIS 概要 B B<-MO=Deparse>[B<,-d>][B<,-f>I][B<,-p>][B<,-q>][B<,-l>] [B<,-s>I][B<,-x>I] I =head1 DESCRIPTION 説明 B::Deparse is a backend module for the Perl compiler that generates perl source code, based on the internal compiled structure that perl itself creates after parsing a program. The output of B::Deparse won't be exactly the same as the original source, since perl doesn't keep track of comments or whitespace, and there isn't a one-to-one correspondence between perl's syntactical constructions and their compiled form, but it will often be close. When you use the B<-p> option, the output also includes parentheses even when they are not required by precedence, which can make it easy to see if perl is parsing your expressions the way you intended. While B::Deparse goes to some lengths to try to figure out what your original program was doing, some parts of the language can still trip it up; it still fails even on some parts of Perl's own test suite. If you encounter a failure other than the most common ones described in the BUGS section below, you can help contribute to B::Deparse's ongoing development by submitting a bug report with a small example. =head1 OPTIONS オプション As with all compiler backend options, these must follow directly after the '-MO=Deparse', separated by a comma but not any white space. 他のコンパイラバックエンドのオプションと同じように, '-MO=Deparse' の後に直接空白を入れずにコンマで区切って指定します. =over 4 =item B<-d> Output data values (when they appear as constants) using Data::Dumper. Without this option, B::Deparse will use some simple routines of its own for the same purpose. Currently, Data::Dumper is better for some kinds of data (such as complex structures with sharing and self-reference) while the built-in routines are better for others (such as odd floating-point values). (データが定数として現れた際に)Data::Dumperを使って出力を行います. このオプションを指定しないときには B::Deparse は自分で持っている簡単な 手続きを使います. 今のところ, 奇妙な浮動小数点数など多くの点では ビルトインのものの方が優れていますが, いくつかのデータ(共有や自己参照を 行う複雑な構造等)に限ると Data::Dumper の方が優れています. =item B<-f>I Normally, B::Deparse deparses the main code of a program, and all the subs defined in the same file. To include subs defined in other files, pass the B<-f> option with the filename. You can pass the B<-f> option several times, to include more than one secondary file. (Most of the time you don't want to use it at all.) You can also use this option to include subs which are defined in the scope of a B<#line> directive with two parameters. 通常 B::Deparse はプログラムのメインコードと同じファイルに含まれる すべての関数をdeparseします. 他のファイルで定義されている関数を含める ためにはB<-f>にファイル名を指定します. B<-f>は複数回指定して複数個の ファイルをを含めることもできます. (多くの場合これを使うことはない でしょう.) このオプションは2パラメータの B<#line> ディレクティブの スコープ内で定義された関数を含めるためにも使えます. =item B<-l> Add '#line' declarations to the output based on the line and file locations of the original code. 元のコードでの行とファイルを元に '#line' 宣言を出力に加えます. =item B<-p> Print extra parentheses. Without this option, B::Deparse includes parentheses in its output only when they are needed, based on the structure of your program. With B<-p>, it uses parentheses (almost) whenever they would be legal. This can be useful if you are used to LISP, or if you want to see how perl parses your input. If you say 括弧を多めに出力します. このオプションを指定しないときには B::Deparse は元のプログラム中で必要な箇所にしか括弧を生成しません. B<-p> を 指定すると(ほとんど)使って問題ない箇所すべてに括弧を生成します. これはLISPに慣れているとか, perl がどのようにパースしたのかを見たい ときには便利でしょう. 次のような入力があったとすると, if ($var & 0x7f == 65) {print "Gimme an A!"} print ($which ? $a : $b), "\n"; $name = $ENV{USER} or "Bob"; C will print C は次のように出力します. if (($var & 0)) { print('Gimme an A!') }; (print(($which ? $a : $b)), '???'); (($name = $ENV{'USER'}) or '???') which probably isn't what you intended (the C<'???'> is a sign that perl optimized away a constant value). そしてこれはおそらく意図したものではないでしょう (C<'???'>は perlが最適化で省略したサインです). =item B<-P> Disable prototype checking. With this option, all function calls are deparsed as if no prototype was defined for them. In other words, プロトタイプチェックを無効にします. このオプションを加えるとすべての 呼び出しはプロトタイプが無かったかのようにdeparseします. いいかえると, 次の文 perl -MO=Deparse,-P -e 'sub foo (\@) { 1 } foo @x' will print は次の出力となります. sub foo (\@) { 1; } &foo(\@x); making clear how the parameters are actually passed to C. パラメータが実際どのように C に渡されるのかが明瞭になります. =item B<-q> Expand double-quoted strings into the corresponding combinations of concatenation, uc, ucfirst, lc, lcfirst, quotemeta, and join. For instance, print ダブルクオート文字列を対応する連結(concatenation), uc, ucfirst, lc, lcfirst, quotemeta, join の組み合わせに展開します. 例えば, 次の例では print "Hello, $world, @ladies, \u$gentlemen\E, \u\L$me!"; as 次のように出力されます. print 'Hello, ' . $world . ', ' . join($", @ladies) . ', ' . ucfirst($gentlemen) . ', ' . ucfirst(lc $me . '!'); Note that the expanded form represents the way perl handles such constructions internally -- this option actually turns off the reverse translation that B::Deparse usually does. On the other hand, note that C<$x = "$y"> is not the same as C<$x = $y>: the former makes the value of $y into a string before doing the assignment. 展開された形式はperlがその様な構成を内部で行っている表現です. この オプションは実際には通常B::Deparseが行っている逆変換でなくなります. 言い換えると, C<$x = "$y"> は C<$x = $y> と同一ではありません. 前者は代入の前に $y を文字列に変換しています. =item B<-s>I Tweak the style of B::Deparse's output. The letters should follow directly after the 's', with no space or punctuation. The following options are available: B::Deparse の出力のスタイルをいじります. I は 's' の直後に続く必要があります. スペースや句読点は必要ありません. 以下のオプションが使用できます: =over 4 =item B Cuddle C, C, and C blocks. For example, print C, C, C ブロックを近くに配置します. 例えば, 次のコード if (...) { ... } else { ... } instead of が次のコードの代わりに出力されます. if (...) { ... } else { ... } The default is not to cuddle. デフォルトではこのオプションは無効です. =item BI Indent lines by multiples of I columns. The default is 4 columns. インデントを I カラム毎に並べます. デフォルトは 4 です. =item B Use tabs for each 8 columns of indent. The default is to use only spaces. For instance, if the style options are B<-si4T>, a line that's indented 3 times will be preceded by one tab and four spaces; if the options were B<-si8T>, the same line would be preceded by three tabs. インデント8カラム毎にタブを使用します. デフォルトではスペースのみ を使用します(訳注:つまりはこのオプションはデフォルトでは無効). 例えば スタイルオプションに B<-si4T> を使用すると, 3回インデントが行われた 行では1つのタブと4つsのスペースが生成されます. オプションに B<-si8T> を使用すると同じ行で3つのタブが生成されます. =item BIB<.> Print I for the value of a constant that can't be determined because it was optimized away (mnemonic: this happens when a constant is used in Boid context). The end of the string is marked by a period. The string should be a valid perl expression, generally a constant. Note that unless it's a number, it probably needs to be quoted, and on a command line quotes need to be protected from the shell. Some conventional values include 0, 1, 42, '', 'foo', and 'Useless use of constant omitted' (which may need to be B<-sv"'Useless use of constant omitted'."> or something similar depending on your shell). The default is '???'. If you're using B::Deparse on a module or other file that's require'd, you shouldn't use a value that evaluates to false, since the customary true constant at the end of a module will be in void context when the file is compiled as a main program. 最適化で取り除かれて確定できない定数値を I で表示します. (覚え方: これは定数がBoidコンテキストで使われたときに発生します.) 文字列の終わりはピリオドでマークします. この文字列は正しいperlの式, 一般的には定数である必要があります. 数字以外を指定する場合には クオートが必要になる点に, そしてコマンドラインでのクオートは シェルからエスケープする必要がある点に注意してください. よくある値としては 0, 1, 42, '', 'foo', そして 'Useless use of constant omitted' ('使われない定数が省略されました'. この指定を行うには B<-sv"'Useless use of constant omitted'."> の様な 感じで指定する必要があるでしょう). デフォルトは '???' です. もしモジュールやrequireしている他のファイルでB::Deparseを使うのなら, 偽として評価される値を使うべきではありません. 慣習的にモジュールの 末尾におかれる真(true)として評価される定数値はメインプログラムとして コンパイルされるときにはvoidコンテキストでの評価となるためです. =back =item B<-x>I Expand conventional syntax constructions into equivalent ones that expose their internal operation. I should be a digit, with higher values meaning more expansion. As with B<-q>, this actually involves turning off special cases in B::Deparse's normal operations. よく使われる構文を内部構造に近い等価なもので展開します. I は 数字である必要があり, 大きい値ほど多くに展開されます. B<-q> の用に, B::Deparse の通常の操作の中において特殊な状況を無効にする必要が実際には生じる こともあります. If I is at least 3, C loops will be translated into equivalent while loops with continue blocks; for instance I が3あると, C ループはcontinueブロックを伴うwhileループに 変換されます. 例えば次の文は for ($i = 0; $i < 10; ++$i) { print $i; } turns into 次のようになります. $i = 0; while ($i < 10) { print $i; } continue { ++$i } Note that in a few cases this translation can't be perfectly carried back into the source code -- if the loop's initializer declares a my variable, for instance, it won't have the correct scope outside of the loop. いくつかのケースでは, この変換は完全にはソースコードには戻らないことが あります. 例えばループ初期化でmy変数を宣言した場合, ループの外側に 対応するスコープは持ちません. If I is at least 5, C declarations will be translated into C blocks containing calls to C and C; for instance, I が5あると, C 宣言が C と C を呼び出す C ブロックに変換されます. 例えば次のコードは use strict 'refs'; turns into 次のようになります. sub BEGIN { require strict; do { 'strict'->import('refs') }; } If I is at least 7, C statements will be translated into equivalent expressions using C<&&>, C and C; for instance Iが7あると, C文がC<&&>, C, C を用いた等価な 式に変換されます. 例えば次の文は print 'hi' if $nice; if ($nice) { print 'hi'; } if ($nice) { print 'hi'; } else { print 'bye'; } turns into 次のようになります. $nice and print 'hi'; $nice and do { print 'hi' }; $nice ? do { print 'hi' } : do { print 'bye' }; Long sequences of elsifs will turn into nested ternary operators, which B::Deparse doesn't know how to indent nicely. elsifの長い列はネストした3項演算になるますが, B::Deparse では 今のところこれをきれいにインデントする方法をしりません. =back =head1 USING B::Deparse AS A MODULE B::Deparse をモジュールとして使う =head2 Synopsis 概要 use B::Deparse; $deparse = B::Deparse->new("-p", "-sC"); $body = $deparse->coderef2text(\&func); eval "sub func $body"; # the inverse operation =head2 Description 説明 B::Deparse can also be used on a sub-by-sub basis from other perl programs. B::Deparse は他のperlプログラムからsub-by-subの原理で使うこともできます. =head2 new $deparse = B::Deparse->new(OPTIONS) Create an object to store the state of a deparsing operation and any options. The options are the same as those that can be given on the command line (see L); options that are separated by commas after B<-MO=Deparse> should be given as separate strings. Some options, like B<-u>, don't make sense for a single subroutine, so don't pass them. deparse操作の状態とオプションを殻のするためのオブジェクトを作成します. オプションはコマンドラインで与えるものと同一です(L参照). B<-MO=Deparse>の後にコンマで区切って与えていたオプションは, バラバラの文字列として与えます. B<-u>の様ないくつかのオプションは 1つの関数としては用をなさないので渡さないでください. (訳注:B<-u>ってなに?) =head2 ambient_pragmas $deparse->ambient_pragmas(strict => 'all', '$[' => $[); The compilation of a subroutine can be affected by a few compiler directives, B. These are: 関数のコンパイル時にはいくつかのコンパイラディレクティブ, B の影響下にあります. それらには以下のものがあります: =over 4 =item * use strict; =item * use warnings; =item * Assigning to the special variable $[ 特殊変数 $] の値 =item * use integer; =item * use bytes; =item * use utf8; =item * use re; =back Ordinarily, if you use B::Deparse on a subroutine which has been compiled in the presence of one or more of these pragmas, the output will include statements to turn on the appropriate directives. So if you then compile the code returned by coderef2text, it will behave the same way as the subroutine which you deparsed. 通常, 1つ以上のこれらのプラグマの環境下でコンパイルされた 関数に対して B::Deparse を使用するのなら, 出力には対応する ディレクティブを有効にする文が含められます. そのため coderef2text が返したコードをコンパイルすると, deparse した関数と同じ振る舞いを 持つようになります. However, you may know that you intend to use the results in a particular context, where some pragmas are already in scope. In this case, you use the B method to describe the assumptions you wish to make. しかし, 結果をいくつかのプラグマで既に有効になっている特定の コンテキストで使うつもりであるのなら, B メソッドを使って環境を仮定すること替えできます. Not all of the options currently have any useful effect. See L for more details. すべてのオプションが意味のある効果を持っているわけでは ありません. L を参照してください. The parameters it accepts are: 使用できるパラメータは以下の通りです: =over 4 =item strict Takes a string, possibly containing several values separated by whitespace. The special values "all" and "none" mean what you'd expect. 文字列を取ります. 通常空白で区切られたいくつかの値からなります. "all" と "none" は特殊な値で, その意味は見た目の通りです. $deparse->ambient_pragmas(strict => 'subs refs'); =item $[ Takes a number, the value of the array base $[. 数字を取ります. この値は配列の基準添字 $[ の値です. =item bytes =item utf8 =item integer If the value is true, then the appropriate pragma is assumed to be in the ambient scope, otherwise not. 値が真であれば対応するプラグマが環境スコープに仮定されます. 真でなければされません. =item re Takes a string, possibly containing a whitespace-separated list of values. The values "all" and "none" are special. It's also permissible to pass an array reference here. $deparser->ambient_pragmas(re => 'eval'); =item warnings Z<> warnings Takes a string, possibly containing a whitespace-separated list of values. The values "all" and "none" are special, again. It's also permissible to pass an array reference here. $deparser->ambient_pragmas(warnings => [qw[void io]]); If one of the values is the string "FATAL", then all the warnings in that list will be considered fatal, just as with the B pragma itself. Should you need to specify that some warnings are fatal, and others are merely enabled, you can pass the B parameter twice: $deparser->ambient_pragmas( warnings => 'all', warnings => [FATAL => qw/void io/], ); See L for more information about lexical warnings. =item hint_bits =item warning_bits These two parameters are used to specify the ambient pragmas in the format used by the special variables $^H and ${^WARNING_BITS}. They exist principally so that you can write code like: { my ($hint_bits, $warning_bits); BEGIN {($hint_bits, $warning_bits) = ($^H, ${^WARNING_BITS})} $deparser->ambient_pragmas ( hint_bits => $hint_bits, warning_bits => $warning_bits, '$[' => 0 + $[ ); } which specifies that the ambient pragmas are exactly those which are in scope at the point of calling. =back =head2 coderef2text $body = $deparse->coderef2text(\&func) $body = $deparse->coderef2text(sub ($$) { ... }) Return source code for the body of a subroutine (a block, optionally preceded by a prototype in parens), given a reference to the sub. Because a subroutine can have no names, or more than one name, this method doesn't return a complete subroutine definition -- if you want to eval the result, you should prepend "sub subname ", or "sub " for an anonymous function constructor. Unless the sub was defined in the main:: package, the code will include a package declaration. 与えられた関数のリファレンスに対応する関数の本体(1つのブロック. 括弧にプロトタイプがつくこともあります)のソースコードを返します. 関数は名前を持たないことも, 2つ以上の名前を持つこともあるため この復帰値は関数名をつけず, 完全な形での関数定義にはなりません. もし結果をevalしたいときには "sub subname " や無名関数であれば "sub "を前につけてください. 関数が main:: パッケージ以外で 定義されているのなら, コードにはパッケージ宣言も含まれているでしょう. =head1 BUGS バグ =over 4 =item * The only pragmas to be completely supported are: C, C, C, and C. (C<$[>, which behaves like a pragma, is also supported.) 完全にサポートしているプラグマは次のものだけです: C, C, C, and C. (プラグマ のように振る舞う C<$[> もサポートされています) Excepting those listed above, we're currently unable to guarantee that B::Deparse will produce a pragma at the correct point in the program. (Specifically, pragmas at the beginning of a block often appear right before the start of the block instead.) Since the effects of pragmas are often lexically scoped, this can mean that the pragma holds sway over a different portion of the program than in the input file. 今挙げたものを除いて, B::Deparse がプログラムの正しい位置に プラグマを生成できるかは保証できません. (特に, ブロックのはじめにある プラグマはしばしばブロックの始まる前に出現します.) プラグマの効果はしばしばレキシカルなスコープにあるため, 入力ファイルとは異なった位置に影響する可能性があることを意味します. =item * In fact, the above is a specific instance of a more general problem: we can't guarantee to produce BEGIN blocks or C declarations in exactly the right place. So if you use a module which affects compilation (such as by over-riding keywords, overloading constants or whatever) then the output code might not work as intended. This is the most serious outstanding problem, and will require some help from the Perl core to fix. =item * If a keyword is over-ridden, and your program explicitly calls the built-in version by using CORE::keyword, the output of B::Deparse will not reflect this. If you run the resulting code, it will call the over-ridden version rather than the built-in one. (Maybe there should be an option to B print keyword calls as C.) =item * Some constants don't print correctly either with or without B<-d>. For instance, neither B::Deparse nor Data::Dumper know how to print dual-valued scalars correctly, as in: use constant E2BIG => ($!=7); $y = E2BIG; print $y, 0+$y; =item * An input file that uses source filtering probably won't be deparsed into runnable code, because it will still include the B declaration for the source filtering module, even though the code that is produced is already ordinary Perl which shouldn't be filtered again. =item * Optimised away statements are rendered as '???'. This includes statements that have a compile-time side-effect, such as the obscure my $x if 0; which is not, consequently, deparsed correctly. =item * There are probably many more bugs on non-ASCII platforms (EBCDIC). =back =head1 AUTHOR 著者 Stephen McCamant , based on an earlier version by Malcolm Beattie , with contributions from Gisle Aas, James Duncan, Albert Dvornik, Robin Houston, Dave Mitchell, Hugo van der Sanden, Gurusamy Sarathy, Nick Ing-Simmons, and Rafael Garcia-Suarez.