5.14.1
Other versions:
5.12.1
5.10.1
5.10.0

名前

perlcompile - Introduction to the Perl Compiler-Translator

perlcompile - Perl コンパイラ・トランスレータの解説

説明

Perl has always had a compiler: your source is compiled into an internal form (a parse tree) which is then optimized before being run. Since version 5.005, Perl has shipped with a module capable of inspecting the optimized parse tree (B), and this has been used to write many useful utilities, including a module that lets you turn your Perl into C source code that can be compiled into a native executable.

Perl は常にコンパイラを持っています: ソースコードは内部コード (構文木) に 変換され、実行する前に最適化されます。 バージョン 5.005 以降、Perl は最適化された構文木 (B) を 調査できる能力があるモジュールとともに配布されており、 このツールは Perl からネイティブな実行ファイルにコンパイルできる C のコードに 変換するモジュールのような様々な便利なユーティリティを記述するのに 用いられています。

The B module provides access to the parse tree, and other modules ("back ends") do things with the tree. Some write it out as semi-human-readable text. Another traverses the parse tree to build a cross-reference of which subroutines, formats, and variables are used where. Another checks your code for dubious constructs. Yet another back end dumps the parse tree back out as Perl source, acting as a source code beautifier or deobfuscator.

B モジュールは構文木にアクセスすることを可能にし、その他のモジュール (「バックエンド」"back ends") はその構文木を利用します。 また、人間がいくらか読みやすく出力するものもあります。 その他の用途としてはサブルーチンの繋がりや変数がどこで使用されているかなどの クロスリファレンスを生成するのに用いられています。 また疑わしい構造に関してコードのチェックにも用いられています。 もう一つのバックエンドとしてコードを整頓し美しく読みやすい Perl ソースとして 再出力します。

Because its original purpose was to be a way to produce C code corresponding to a Perl program, and in turn a native executable, the B module and its associated back ends are known as "the compiler", even though they don't really compile anything. Different parts of the compiler are more accurately a "translator", or an "inspector", but people want Perl to have a "compiler option" not an "inspector gadget". What can you do?

元々の目的が Perl プログラムと等価な C 言語のコードを提供し、ネイティブな 実行可能ファイルにすることであったので、本来何もコンパイルはしないのですが、 現在 B モジュールは「コンパイラ」として知られています。 このコンパイラは正確に言うとトランスレータやインスペクタに近いですが、 人々は Perl にインスペクタツールではなくコンパイラオプションを 持ってほしいと思っています。 あなたには何ができますか?

This document covers the use of the Perl compiler: which modules it comprises, how to use the most important of the back end modules, what problems there are, and how to work around them.

この文書は Perl コンパイラについて解説しています: Perl コンパイラを 構成しているモジュール、バックエンドモジュールの使い方、そしてそこに どのような問題があるかです。

構成

The compiler back ends are in the B:: hierarchy, and the front-end (the module that you, the user of the compiler, will sometimes interact with) is the O module.

コンパイラのバックエンドは B:: 以下に入っていて、(あなたや、コンパイラ 利用者が使うであろう) フロントエンドは O モジュールです。

Here are the important back ends to know about, with their status expressed as a number from 0 (outline for later implementation) to 10 (if there's a bug in it, we're very surprised):

以下は知っておくべき重要なバックエンドのリストで、それぞれ 0 (今後 実装するためのアウトラインの段階) から10 (もしバグが あったらとても驚きます) のステータス番号は作業進行度を表しています:

B::Lint

Complains if it finds dubious constructs in your source code. Status: 6 (it works adequately, but only has a very limited number of areas that it checks).

あなたのコードのに疑わしい部分があれば警告します。 ステータス: 6 (適切に動作しますが、限られたエリアしかチェックしません)。

B::Deparse

Recreates the Perl source, making an attempt to format it coherently. Status: 8 (it works nicely, but a few obscure things are missing).

フォーマットが一貫しているか注意しながらの Perl ソースの再構成を行います。 ステータス: 8 (ほぼ正確に動作しますが、いくつかの不明瞭なものは 欠けています)。

B::Xref

Reports on the declaration and use of subroutines and variables. Status: 8 (it works nicely, but still has a few lingering bugs).

変数やサブルーチンの宣言と使用を報告します。 ステータス: 8 (よく動きますが、まだいくつかの根深いバグがあります)。

バックエンドを使う

The following sections describe how to use the various compiler back ends. They're presented roughly in order of maturity, so that the most stable and proven back ends are described first, and the most experimental and incomplete back ends are described last.

以下の節ではどのようにコンパイラのバックエンドを利用するかを解説します。 これらはおよそ成熟度の順に並んでいるので、最も安定していて 検証されているバックエンドを最初に解説し、最も実験的で不完全な バックエンドを最後に解説します。

The O module automatically enabled the -c flag to Perl, which prevents Perl from executing your code once it has been compiled. This is why all the back ends print:

O モジュールは -c フラグを Perl に渡すことで自動的に有効になり、 Perl はコードを実行せずにコンパイルだけを行います。 これが全てのバックエンドが以下のように表示する理由です:

  myperlprogram syntax OK

before producing any other output.

すべての出力に先立ってこのような表示がなされます。

クロスリファレンスのバックエンド

The cross-referencing back end (B::Xref) produces a report on your program, breaking down declarations and uses of subroutines and variables (and formats) by file and subroutine. For instance, here's part of the report from the pod2man program that comes with Perl:

クロスリファレンスを作成するバックエンド (B::Xref) は変数の宣言や サブルーチンの使用法などの分析を行ったレポートを作成します。 例えば、以下は Perl に同梱されている pod2man プログラムのレポートです:

  Subroutine clear_noremap
    Package (lexical)
      $ready_to_print   i1069, 1079
    Package main
      $&                1086
      $.                1086
      $0                1086
      $1                1087
      $2                1085, 1085
      $3                1085, 1085
      $ARGV             1086
      %HTML_Escapes     1085, 1085

This shows the variables used in the subroutine clear_noremap. The variable $ready_to_print is a my() (lexical) variable, introduced (first declared with my()) on line 1069, and used on line 1079. The variable $& from the main package is used on 1086, and so on.

これは clear_noremap で用いられている変数を表示しています。 $ready_to_print という変数は my()(レキシカル) 変数で、1069 行目で (my() で宣言されて)導入され、1079 行目で使われています。 main パッケージの $& という変数は 1086 行目で使われている、などです。

A line number may be prefixed by a single letter:

行番号は以下の接頭辞を伴って出力されます:

i

Lexical variable introduced (declared with my()) for the first time.

レキシカル変数が最初に (my() で宣言されて) 導入された。

&

Subroutine or method call.

サブルーチンまたはメソッド呼び出し。

s

Subroutine defined.

サブルーチンが定義された。

r

Format defined.

フォーマットが定義された。

The most useful option the cross referencer has is to save the report to a separate file. For instance, to save the report on myperlprogram to the file report:

クロスリファレンスを作成するにあたり最も有用なオプションとしてレポートを 複数のファイルに分割して保存するというものがあります。 たとえば myperlprogram のレポートと report ファイルに保存するには:

  $ perl -MO=Xref,-oreport myperlprogram

逆コンパイルバックエンド

The Deparse back end turns your Perl source back into Perl source. It can reformat along the way, making it useful as a deobfuscator. The most basic way to use it is:

Deparse バックエンドはあなたの Perl ソースが Perl コンパイラにどのように パースされたかを表示します。 この出力は読みやすいように整形することができます。 基本的な使用法は以下の通りです:

  $ perl -MO=Deparse myperlprogram

You'll notice immediately that Perl has no idea of how to paragraph your code. You'll have to separate chunks of code from each other with newlines by hand. However, watch what it will do with one-liners:

出力を見ると、Perl がコードをどのように整形すべきか 分かっていないことが分かるでしょう。 あなたはコードのブロックごとに自分で改行することになるでしょう。 しかし、その作業は以下の一行野郎で可能です:

  $ perl -MO=Deparse -e '$op=shift||die "usage: $0
  code [...]";chomp(@ARGV=<>)unless@ARGV; for(@ARGV){$was=$_;eval$op;
  die$@ if$@; rename$was,$_ unless$was eq $_}'
  -e syntax OK
  $op = shift @ARGV || die("usage: $0 code [...]");
  chomp(@ARGV = <ARGV>) unless @ARGV;
  foreach $_ (@ARGV) {
      $was = $_;
      eval $op;
      die $@ if $@;
      rename $was, $_ unless $was eq $_;
  }

The decompiler has several options for the code it generates. For instance, you can set the size of each indent from 4 (as above) to 2 with:

逆コンパイラは生成するコードに対するオプションを持っています。 例えば、インデントの量を (上述のような) 4 から 2 に変更できます:

  $ perl -MO=Deparse,-si2 myperlprogram

The -p option adds parentheses where normally they are omitted:

-p オプションは普通省略可能なところにかっこを挿入します:

  $ perl -MO=Deparse -e 'print "Hello, world\n"'
  -e syntax OK
  print "Hello, world\n";
  $ perl -MO=Deparse,-p -e 'print "Hello, world\n"'
  -e syntax OK
  print("Hello, world\n");

See B::Deparse for more information on the formatting options.

その他のフォーマットオプションは B::Deparse を参照してください。

Lint バックエンド

The lint back end (B::Lint) inspects programs for poor style. One programmer's bad style is another programmer's useful tool, so options let you select what is complained about.

Lint バックエンド (B::Lint) は良くないスタイルのプログラムを調査します。 あるプログラマの間違ったスタイルは他のプログラマの学習を促進します; よってどのような事について警告するかオプションで設定できます。

To run the style checker across your source code:

スタイルチェッカーをソースコードに対して実行するには:

  $ perl -MO=Lint myperlprogram

To disable context checks and undefined subroutines:

コンテキストのチェックと未定義のサブルーチンを無効にするには:

  $ perl -MO=Lint,-context,-undefined-subs myperlprogram

See B::Lint for information on the options.

その他のオプションについては B::Lint を参照してください。

コンパイラに関するモジュールのリスト

B

This module is the introspective ("reflective" in Java terms) module, which allows a Perl program to inspect its innards. The back end modules all use this module to gain access to the compiled parse tree. You, the user of a back end module, will not need to interact with B.

このモジュールは Perl プログラム内の機構を内省する (Java の用語では「リフレクションする」) モジュールで、Perl プログラムが その内部を調べられるようにします。 バックエンドモジュールはコンパイルされた構文木にアクセスする機能を提供します。 バックエンドモジュールのユーザーは B に関する経験は問われません。

O

This module is the front-end to the compiler's back ends. Normally called something like this:

このモジュールはコンパイラのバックエンドのフロントエンドモジュールです。 通常では以下のような感じで利用します:

  $ perl -MO=Deparse myperlprogram

This is like saying use O 'Deparse' in your Perl program.

これは use O 'Deparse' があなたのプログラムに含まれているようにします。

B::Concise

This module prints a concise (but complete) version of the Perl parse tree. Its output is more customizable than the one of B::Terse or B::Debug (and it can emulate them). This module is useful for people who are writing their own back end, or who are learning about the Perl internals. It's not useful to the average programmer.

このモジュールは簡潔な (しかし完全な) Perl 構文木を表示します。 このモジュールの出力は B::Terse や B::Debug よりもカスタマイズ可能です (またそれらをエミュレートすることも可能です)。 このモジュールはバックエンドを書いている人や、Perl の内部構造を学びたい人に 有用です。 平均的なプログラマには役に立たないでしょう。

B::Debug

This module dumps the Perl parse tree in verbose detail to STDOUT. It's useful for people who are writing their own back end, or who are learning about the Perl internals. It's not useful to the average programmer.

このモジュールは Perl 構文木を詳細に STDOUT にダンプします。 このモジュールはバックエンドを書いている人や Perl の内部構造を学びたい人に 有用です。 平均的なプログラマには役に立たないでしょう。

B::Deparse

This module produces Perl source code from the compiled parse tree. It is useful in debugging and deconstructing other people's code, also as a pretty-printer for your own source. See "The Decompiling Back End" for details about usage.

このモジュールは Perl コードのコンパイルされた構文木を提供します。 このモジュールは他人の書いたコードをデバッグ再構成しようとしている人に 役立つでしょう。 また自分のコードを綺麗に出力するのにも役立ちます。 使用法の詳細は "The Decompiling Back End" を参照してください。

B::Lint

This module inspects the compiled form of your source code for things which, while some people frown on them, aren't necessarily bad enough to justify a warning. For instance, use of an array in scalar context without explicitly saying scalar(@array) is something that Lint can identify. See "The Lint Back End" for details about usage.

このモジュールはコンパイルされたソースコードを分析します; これは 一部の人は難色を示すものの、警告を出すほど悪いものではないものです。 例えば、配列を scalar(@array) することなくスカラコンテキストとして 使用するというのは Lint が識別できるものです。 使用法の詳細は "The Lint Back End" を参照してください。

B::Showlex

This module prints out the my() variables used in a function or a file. To get a list of the my() variables used in the subroutine mysub() defined in the file myperlprogram:

このモジュールは関数内およびファイル内で使用されている my() で 宣言された変数を表示します。 myperlprogram 内で定義された mysub() サブルーチン内で使用されている my() で宣言された変数を取得するには以下のようにします:

  $ perl -MO=Showlex,mysub myperlprogram

To get a list of the my() variables used in the file myperlprogram:

myperlprogram 内で使用されている my() で宣言された変数を取得するには 以下のようにします:

  $ perl -MO=Showlex myperlprogram

[BROKEN]

[BROKEN]

B::Terse

This module prints the contents of the parse tree, but without as much information as B::Debug. For comparison, print "Hello, world." produced 96 lines of output from B::Debug, but only 6 from B::Terse.

このモジュールは構文木の内容を出力しますが、B::Debug より得られる 情報は少ないです。 比較のための例として print "Hello, world." について B::Debug は 96 行もの 情報を出力しますが、B::Terse は 6 行しか出力しません。

This module is useful for people who are writing their own back end, or who are learning about the Perl internals. It's not useful to the average programmer.

このモジュールは自分のプログラムのバックエンドを書いている人及び Perl の 内部について学ぼうとしている人に役立つでしょう。 平均的なプログラマには役に立たないでしょう。

B::Xref

This module prints a report on where the variables, subroutines, and formats are defined and used within a program and the modules it loads. See "The Cross-Referencing Back End" for details about usage.

このモジュールは変数、サブルーチン、プログラム内で使用されたフォーマット、 モジュールのロードそれぞれの場所についてレポートを出力します。 使用法の詳細は "The Cross-Referencing Back End" を参照してください。

既知の不具合

BEGIN{} blocks are executed while compiling your code. Any external state that is initialized in BEGIN{}, such as opening files, initiating database connections etc., do not behave properly. To work around this, Perl has an INIT{} block that corresponds to code being executed before your program begins running but after your program has finished being compiled. Execution order: BEGIN{}, (possible save of state through compiler back-end), INIT{}, program runs, END{}.

BEGIN{} ブロックはコードがコンパイルされる段階で実行されてしまいます。 ファイルを開いたり、データベース接続を初期化したりといった、 BEGIN{} 内での外部状態の初期化は正しく動作しません。 これに対応するに、Perl には INIT{} ブロック構文があります; この構文はあなたのコードがコンパイルされたあと、実行される前に 処理されます。 実行される順序: BEGIN{} ブロック、(コンパイラのバックエンドを用いて状態を 保存できます) 、INIT{}ブロック、コードの実行、END{}ブロック。

作者

This document was originally written by Nathan Torkington, and is now maintained by the perl5-porters mailing list perl5-porters@perl.org.

このドキュメントは Nathan Torkington によって書かれ、現在は perl5-porters のメーリングリスト perl5-porters@perl.org によって 保守されています。