B::Deparse - Perl compiler backend to produce perl code

目次


NAME 名前

B::Deparse - Perl compiler backend to produce perl code

B::Deparse - perl コードを生成するPerlコンパイラバックエンド


SYNOPSIS 概要

perl -MO=Deparse[,-d][,-fFILE][,-p][,-q][,-l] [,-sLETTERS][,-xLEVEL] prog.pl


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 -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.


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' の後に直接空白を入れずにコンマで区切って指定します.

-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 の方が優れています.

-fFILE

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 -f option with the filename. You can pass the -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 #line directive with two parameters.

通常 B::Deparse はプログラムのメインコードと同じファイルに含まれる すべての関数をdeparseします. 他のファイルで定義されている関数を含める ためには-fにファイル名を指定します. -fは複数回指定して複数個の ファイルをを含めることもできます. (多くの場合これを使うことはない でしょう.) このオプションは2パラメータの #line ディレクティブの スコープ内で定義された関数を含めるためにも使えます.

-l

Add '#line' declarations to the output based on the line and file locations of the original code.

元のコードでの行とファイルを元に '#line' 宣言を出力に加えます.

-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 -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 は元のプログラム中で必要な箇所にしか括弧を生成しません. -p を 指定すると(ほとんど)使って問題ない箇所すべてに括弧を生成します. これはLISPに慣れているとか, perl がどのようにパースしたのかを見たい ときには便利でしょう. 次のような入力があったとすると,

    if ($var & 0x7f == 65) {print "Gimme an A!"}
    print ($which ? $a : $b), "\n";
    $name = $ENV{USER} or "Bob";

B::Deparse,-p will print

B::Deparse,-p は次のように出力します.

    if (($var & 0)) {
        print('Gimme an A!')
    };
    (print(($which ? $a : $b)), '???');
    (($name = $ENV{'USER'}) or '???')

which probably isn't what you intended (the '???' is a sign that perl optimized away a constant value).

そしてこれはおそらく意図したものではないでしょう ('???'は perlが最適化で省略したサインです).

-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 foo.

パラメータが実際どのように foo に渡されるのかが明瞭になります.

-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 $x = "$y" is not the same as $x = $y: the former makes the value of $y into a string before doing the assignment.

展開された形式はperlがその様な構成を内部で行っている表現です. この オプションは実際には通常B::Deparseが行っている逆変換でなくなります. 言い換えると, $x = "$y"$x = $y と同一ではありません. 前者は代入の前に $y を文字列に変換しています.

-sLETTERS

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 の出力のスタイルをいじります. LETTERS は 's' の直後に続く必要があります. スペースや句読点は必要ありません. 以下のオプションが使用できます:

C

Cuddle elsif, else, and continue blocks. For example, print

elsif, else, continue ブロックを近くに配置します. 例えば, 次のコード

    if (...) {
         ...
    } else {
         ...
    }

instead of

が次のコードの代わりに出力されます.

    if (...) {
         ...
    }
    else {
         ...
    }

The default is not to cuddle.

デフォルトではこのオプションは無効です.

iNUMBER

Indent lines by multiples of NUMBER columns. The default is 4 columns.

インデントを NUMBER カラム毎に並べます. デフォルトは 4 です.

T

Use tabs for each 8 columns of indent. The default is to use only spaces. For instance, if the style options are -si4T, a line that's indented 3 times will be preceded by one tab and four spaces; if the options were -si8T, the same line would be preceded by three tabs.

インデント8カラム毎にタブを使用します. デフォルトではスペースのみ を使用します(訳注:つまりはこのオプションはデフォルトでは無効). 例えば スタイルオプションに -si4T を使用すると, 3回インデントが行われた 行では1つのタブと4つsのスペースが生成されます. オプションに -si8T を使用すると同じ行で3つのタブが生成されます.

vSTRING.

Print STRING 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 void 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 -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.

最適化で取り除かれて確定できない定数値を STRING で表示します. (覚え方: これは定数がvoidコンテキストで使われたときに発生します.) 文字列の終わりはピリオドでマークします. この文字列は正しいperlの式, 一般的には定数である必要があります. 数字以外を指定する場合には クオートが必要になる点に, そしてコマンドラインでのクオートは シェルからエスケープする必要がある点に注意してください. よくある値としては 0, 1, 42, '', 'foo', そして 'Useless use of constant omitted' ('使われない定数が省略されました'. この指定を行うには -sv"'Useless use of constant omitted'." の様な 感じで指定する必要があるでしょう). デフォルトは '???' です. もしモジュールやrequireしている他のファイルでB::Deparseを使うのなら, 偽として評価される値を使うべきではありません. 慣習的にモジュールの 末尾におかれる真(true)として評価される定数値はメインプログラムとして コンパイルされるときにはvoidコンテキストでの評価となるためです.

-xLEVEL

Expand conventional syntax constructions into equivalent ones that expose their internal operation. LEVEL should be a digit, with higher values meaning more expansion. As with -q, this actually involves turning off special cases in B::Deparse's normal operations.

よく使われる構文を内部構造に近い等価なもので展開します. LEVEL は 数字である必要があり, 大きい値ほど多くに展開されます. -q の用に, B::Deparse の通常の操作の中において特殊な状況を無効にする必要が実際には生じる こともあります.

If LEVEL is at least 3, for loops will be translated into equivalent while loops with continue blocks; for instance

LEVEL が3あると, for ループは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 LEVEL is at least 5, use declarations will be translated into BEGIN blocks containing calls to require and import; for instance,

LEVEL が5あると, use 宣言が requireimport を呼び出す BEGIN ブロックに変換されます. 例えば次のコードは

    use strict 'refs';

turns into

次のようになります.

    sub BEGIN {
        require strict;
        do {
            'strict'->import('refs')
        };
    }

If LEVEL is at least 7, if statements will be translated into equivalent expressions using &&, ?: and do {}; for instance

LEVELが7あると, if文が&&, ?:, do {} を用いた等価な 式に変換されます. 例えば次の文は

    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 では 今のところこれをきれいにインデントする方法をしりません.


USING B::Deparse AS A MODULE B::Deparse をモジュールとして使う

Synopsis 概要

    use B::Deparse;
    $deparse = B::Deparse->new("-p", "-sC");
    $body = $deparse->coderef2text(\&func);
    eval "sub func $body"; # the inverse operation

Description 説明

B::Deparse can also be used on a sub-by-sub basis from other perl programs.

B::Deparse は他のperlプログラムからsub-by-subの原理で使うこともできます.

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 "OPTIONS"); options that are separated by commas after -MO=Deparse should be given as separate strings. Some options, like -u, don't make sense for a single subroutine, so don't pass them.

deparse操作の状態とオプションを殻のするためのオブジェクトを作成します. オプションはコマンドラインで与えるものと同一です("OPTIONS"参照). -MO=Deparseの後にコンマで区切って与えていたオプションは, バラバラの文字列として与えます. -uの様ないくつかのオプションは 1つの関数としては用をなさないので渡さないでください. (訳注:-uってなに?)

ambient_pragmas

    $deparse->ambient_pragmas(strict => 'all', '$[' => $[);

The compilation of a subroutine can be affected by a few compiler directives, pragmas. These are:

関数のコンパイル時にはいくつかのコンパイラディレクティブ, pragma の影響下にあります. それらには以下のものがあります:

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 ambient_pragmas method to describe the assumptions you wish to make.

しかし, 結果をいくつかのプラグマで既に有効になっている特定の コンテキストで使うつもりであるのなら, ambient_pragmas メソッドを使って環境を仮定すること替えできます.

Not all of the options currently have any useful effect. See "BUGS" for more details.

すべてのオプションが意味のある効果を持っているわけでは ありません. "BUGS" を参照してください.

The parameters it accepts are:

使用できるパラメータは以下の通りです:

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');
$[

Takes a number, the value of the array base $[.

数字を取ります. この値は配列の基準添字 $[ の値です.

bytes
utf8
integer

If the value is true, then the appropriate pragma is assumed to be in the ambient scope, otherwise not.

値が真であれば対応するプラグマが環境スコープに仮定されます. 真でなければされません.

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');
警告

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 warnings pragma itself. Should you need to specify that some warnings are fatal, and others are merely enabled, you can pass the warnings parameter twice:

    $deparser->ambient_pragmas(
	warnings => 'all',
	warnings => [FATAL => qw/void io/],
    );

See perllexwarn [CPAN] for more information about lexical warnings.

hint_bits
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.

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:: パッケージ以外で 定義されているのなら, コードにはパッケージ宣言も含まれているでしょう.


BUGS バグ


AUTHOR 著者

Stephen McCamant <smcc@CSUA.Berkeley.EDU>, based on an earlier version by Malcolm Beattie <mbeattie@sable.ox.ac.uk>, 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.

B::Deparse - Perl compiler backend to produce perl code

索引

B::Deparse - Perl compiler backend to produce perl code