=encoding euc-jp =head1 NAME =begin original perlhack - How to hack at the Perl internals =end original perlhack - Perl の内部をハックする方法 =head1 DESCRIPTION =begin original This document attempts to explain how Perl development takes place, and ends with some suggestions for people wanting to become bona fide porters. =end original この文書は、Perl 開発がどのように行われているかを説明しようと試み、最後に 正真正銘の porters になりたい人々に対する提案が付いています。 =begin original The perl5-porters mailing list is where the Perl standard distribution is maintained and developed. The list can get anywhere from 10 to 150 messages a day, depending on the heatedness of the debate. Most days there are two or three patches, extensions, features, or bugs being discussed at a time. =end original perl5-porters メーリングリストは Perl 標準配布の保守と開発を行っている 場所です。 リストには議論の白熱度に応じて一日に 10 から 150 のメッセージが流れます。 ほとんどの場合 2 または 3 のパッチ、エクステンション、機能、バグが 同時に議論されています。 =begin original A searchable archive of the list is at either: =end original メーリングリストの検索可能なアーカイブは以下の場所か: http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/ =begin original or =end original または http://archive.develooper.com/perl5-porters@perl.org/ =begin original List subscribers (the porters themselves) come in several flavours. Some are quiet curious lurkers, who rarely pitch in and instead watch the ongoing development to ensure they're forewarned of new changes or features in Perl. Some are representatives of vendors, who are there to make sure that Perl continues to compile and work on their platforms. Some patch any reported bug that they know how to fix, some are actively patching their pet area (threads, Win32, the regexp engine), while others seem to do nothing but complain. In other words, it's your usual mix of technical people. =end original リスト登録者(porters 自身)にはいくつかの種類があります。 中には静かで好奇心旺盛な人もいて、めったに協力しない代わりに進行中の開発を 監視して、Perl の新しい変更や機能について事前に警告されていることを 確認している人もいます。 中にはベンダーの代表者もいて、Perl が自分たちのプラットフォームで コンパイルと作業を継続していることを確認している人もいます。 報告されたバグの修正方法を知っているパッチを当てる人もいれば、 自分たちの得意分野(スレッド、Win32、正規表現エンジン)に 積極的にパッチを当てる人もいれば、文句ばかり言っている人もいます。 言い換えれば、これは通常の技術者の組み合わせです。 =begin original Over this group of porters presides Larry Wall. He has the final word in what does and does not change in the Perl language. Various releases of Perl are shepherded by a "pumpking", a porter responsible for gathering patches, deciding on a patch-by-patch, feature-by-feature basis what will and will not go into the release. For instance, Gurusamy Sarathy was the pumpking for the 5.6 release of Perl, and Jarkko Hietaniemi was the pumpking for the 5.8 release, and Rafael Garcia-Suarez holds the pumpking crown for the 5.10 release. =end original Larry Wall は、Perl 言語で何が変更され、何が変更されないかについて 最終的な決定権を持っています。 Perl のさまざまなリリースでは、パッチを収集し、パッチ上ごとに、機能ごとに、 リリースで何が変更され、何が変更されないかを決定する責任を負う "pumpking" によって管理されています。 たとえば、Gurusamy Sarthy は 5.6 のPerlリリースの pumpking を務め、 Jarkko Hietaniemi は 5.8 のリリースの pumpking を務め、 Rafael Garcia-Suarez は 5.10 のリリースの pumpking を務めています。 =begin original In addition, various people are pumpkings for different things. For instance, Andy Dougherty and Jarkko Hietaniemi did a grand job as the I pumpkin up till the 5.8 release. For the 5.10 release H.Merijn Brand took over. =end original また、いろいろな人がいろいろなことで pumpking になっています。 例えば、Andy Dougherty と Jarkko Hietaniemi は、5.8 リリースまでは I pumpking として大きな仕事をしていました。 5.10 リリースでは H.Merijn Brand が引き継ぎました。 =begin original Larry sees Perl development along the lines of the US government: there's the Legislature (the porters), the Executive branch (the pumpkings), and the Supreme Court (Larry). The legislature can discuss and submit patches to the executive branch all they like, but the executive branch is free to veto them. Rarely, the Supreme Court will side with the executive branch over the legislature, or the legislature over the executive branch. Mostly, however, the legislature and the executive branch are supposed to get along and work out their differences without impeachment or court cases. =end original Larry は、Perl 開発は米国政府の方針に沿ったものだと考えています。 議会(porters)、行政府(pumpking)、そして最高裁判所(Larry)があります。 議会は行政府に対して好きなだけ議論してパッチを提出することができますが、 行政府は自由に拒否権を行使することができます。 まれに、最高裁判所が立法府おyり行政府に味方したり、行政府より立法府に 味方することがあります。 しかし、ほとんどの場合、立法府と行政府は、弾劾や裁判なしに 意見の相違を調整することになっています。 =begin original You might sometimes see reference to Rule 1 and Rule 2. Larry's power as Supreme Court is expressed in The Rules: =end original Rule 1 と Rule 2 を参照しているのをみたことがあるかもしれません。 Larry の最高裁としての権力は、The Rules で次のように表現されています。 =over 4 =item 1 =begin original Larry is always by definition right about how Perl should behave. This means he has final veto power on the core functionality. =end original Larry は、定義上、Perl がどのように振る舞うべきかについて常に正しいです。 これは、彼がコア機能に対する最終的な拒否権を持っていることを意味します。 =item 2 =begin original Larry is allowed to change his mind about any matter at a later date, regardless of whether he previously invoked Rule 1. =end original Larry は、以前に Rule 1 を発動したかどうかにかかわらず、 いかなる問題についても後で考えを変えることが許されます。 =back =begin original Got that? Larry is always right, even when he was wrong. It's rare to see either Rule exercised, but they are often alluded to. =end original わかりましたか? Larry は、たとえ間違っていても、常に正しいです。 どちらのルールが実行されているのを見ることはまれですが、 それらはしばしば暗に言及されます。 =begin original New features and extensions to the language are contentious, because the criteria used by the pumpkings, Larry, and other porters to decide which features should be implemented and incorporated are not codified in a few small design goals as with some other languages. Instead, the heuristics are flexible and often difficult to fathom. Here is one person's list, roughly in decreasing order of importance, of heuristics that new features have to be weighed against: =end original pumpking や Larry、その他の porters がどの機能を実装して組み込むかを 決定するために使った基準が、他の言語のようにいくつかの小さな設計目標に 成文化されていないため、新しい機能や言語の拡張には議論の余地があります。 代わりに、ヒューリスティックスは柔軟性があり、多くの場合、理解するのが 困難です。 ここでは、ある個人が、新しい機能を比較検討する必要がある ヒューリスティックスを、重要度の高い順にまとめたリストを示します。 =over 4 =item Does concept match the general goals of Perl? =begin original These haven't been written anywhere in stone, but one approximation is: =end original これらはどこにも明文化されていませんが、次のような近似があります: 1. Keep it fast, simple, and useful. 2. Keep features/concepts as orthogonal as possible. 3. No arbitrary limits (platforms, data sizes, cultures). 4. Keep it open and exciting to use/patch/advocate Perl everywhere. 5. Either assimilate new technologies, or build bridges to them. =item Where is the implementation? =begin original All the talk in the world is useless without an implementation. In almost every case, the person or people who argue for a new feature will be expected to be the ones who implement it. Porters capable of coding new features have their own agendas, and are not available to implement your (possibly good) idea. =end original 実装なしでは、世界のすべての話は役に立ちません。 ほとんどすべての場合、新機能を主張する人は、それを実装する人であることが 期待されます。 新機能をコーディングできる porters は独自のアジェンダを持っており、 あなたの(おそらく良い)アイデアを実装するためには利用できません。 =item Backwards compatibility =begin original It's a cardinal sin to break existing Perl programs. New warnings are contentious--some say that a program that emits warnings is not broken, while others say it is. Adding keywords has the potential to break programs, changing the meaning of existing token sequences or functions might break programs. =end original 既存の Perl プログラムを破壊することは重大な罪です。 新しい警告については議論の余地があります -- 警告を発するプログラムは破壊されないとする人もいれば、 破壊されるとする人もいます。 キーワードを追加するとプログラムが破壊される可能性があり、 既存のトークンシーケンスや関数の意味を変更すると プログラムが破壊される可能性があります。 =item Could it be a module instead? =begin original Perl 5 has extension mechanisms, modules and XS, specifically to avoid the need to keep changing the Perl interpreter. You can write modules that export functions, you can give those functions prototypes so they can be called like built-in functions, you can even write XS code to mess with the runtime data structures of the Perl interpreter if you want to implement really complicated things. If it can be done in a module instead of in the core, it's highly unlikely to be added. =end original Perl 5 には、 特に Perl インタプリタを変更し続ける必要がないようにするための、 拡張メカニズム、モジュール、XS があります。 関数をエクスポートするモジュールを書くこともできますし、 組み込み関数のように呼び出すことができるように 関数にプロトタイプを与えることもできますし、 非常に複雑なことを実装したい場合には、 Perl インタプリタの実行時データ構造をいじる XS コードを書くこともできます。 コアではなくモジュールで行うことができる場合は、 追加される可能性は非常に低くなります。 =item Is the feature generic enough? =begin original Is this something that only the submitter wants added to the language, or would it be broadly useful? Sometimes, instead of adding a feature with a tight focus, the porters might decide to wait until someone implements the more generalized feature. For instance, instead of implementing a "delayed evaluation" feature, the porters are waiting for a macro system that would permit delayed evaluation and much more. =end original これは投稿者だけが言語に追加したいと思っているものなのでしょうか、 それとも広く有用なものなのでしょうか? 時には、焦点を絞った機能を追加する代わりに、 porters は誰かがより一般的な機能を実装するまで待つことに決めるかもしれません。 例えば、「遅延評価」機能を実装する代わりに、 porters は遅延評価などを可能にするマクロシステムを待っています。 =item Does it potentially introduce new bugs? =begin original Radical rewrites of large chunks of the Perl interpreter have the potential to introduce new bugs. The smaller and more localized the change, the better. =end original Perl インタプリタの大きな部分を大幅に書き換えてしまうと、 新しいバグが発生する可能性があります。 変化が小さく、局所的であればあるほど良いです。 =item Does it preclude other desirable features? =begin original A patch is likely to be rejected if it closes off future avenues of development. For instance, a patch that placed a true and final interpretation on prototypes is likely to be rejected because there are still options for the future of prototypes that haven't been addressed. =end original パッチが将来の開発の道を閉ざす場合、 パッチは却下される可能性が高いです。 例えば、プロトタイプに真の最終解釈を置いたパッチは、 まだ対処されていないプロトタイプの将来の選択肢がまだあるため、 却下される可能性が高いです。 =item Is the implementation robust? =begin original Good patches (tight code, complete, correct) stand more chance of going in. Sloppy or incorrect patches might be placed on the back burner until the pumpking has time to fix, or might be discarded altogether without further notice. =end original 優れたパッチ(厳密なコード、完全なパッチ、正しいパッチ)は、 入り込む可能性が高くなります。 ずさんなパッチや正しくないパッチは、pumpking が修正する時間があるまで 後回しにされたり、通知なしに完全に廃棄されたりします。 =item Is the implementation generic enough to be portable? =begin original The worst patches make use of a system-specific features. It's highly unlikely that non-portable additions to the Perl language will be accepted. =end original 最悪のパッチは、システム固有の機能を利用しています。 移植性のない Perl 言語への追加が受け入れられる可能性はほとんどありません。 =item Is the implementation tested? =begin original Patches which change behaviour (fixing bugs or introducing new features) must include regression tests to verify that everything works as expected. Without tests provided by the original author, how can anyone else changing perl in the future be sure that they haven't unwittingly broken the behaviour the patch implements? And without tests, how can the patch's author be confident that his/her hard work put into the patch won't be accidentally thrown away by someone in the future? =end original 動作を変更するパッチ(バグの修正や新機能の導入)には、 すべてが期待通りに動作することを検証するための 回帰テストを含める必要があります。 元の著者が提供したテストがなければ、将来 Perl を変更する他の人が、 パッチが実装している動作を無意識のうちに破壊していないことを 確認するにはどうすればよいでしょうか? また、テストがなければ、パッチの作成者は、 パッチに加えた自分の苦労が将来誰かによって誤って捨てられないと 確信するにはどうすればよいでしょうか? =item Is there enough documentation? =begin original Patches without documentation are probably ill-thought out or incomplete. Nothing can be added without documentation, so submitting a patch for the appropriate manpages as well as the source code is always a good idea. =end original 文書のないパッチは、おそらく間違っているか不完全です。 文書なしでは何も追加できないので、ソースコードとともに適切な man ページのパッチを提出することは常に良い考えです。 =item Is there another way to do it? =begin original Larry said "Although the Perl Slogan is I, I hesitate to make 10 ways to do something". This is a tricky heuristic to navigate, though--one man's essential addition is another man's pointless cruft. =end original Larry は、「Perl のスローガンはI ですが、 何かを行うための 10 の方法を作ることにはためらいがあります」と述べています。 しかし、これは運営のための巧妙なヒューリスティックです -- ある人の 本質的な追加は、別の人の無意味なたわごとです。 =item Does it create too much work? =begin original Work for the pumpking, work for Perl programmers, work for module authors, ... Perl is supposed to be easy. =end original pumpking の仕事、Perl プログラマーの仕事、モジュール作成者の仕事…。 Perl は簡単なはずです。 =item Patches speak louder than words =begin original Working code is always preferred to pie-in-the-sky ideas. A patch to add a feature stands a much higher chance of making it to the language than does a random feature request, no matter how fervently argued the request might be. This ties into "Will it be useful?", as the fact that someone took the time to make the patch demonstrates a strong desire for the feature. =end original 動作するコードは、絵に描いた餅のアイデアよりも常に好まれます。 機能を追加するパッチは、ランダムな機能リクエストよりも、 そのリクエストがどんなに熱心に議論されたとしても、 言語に取り入れられる可能性がはるかに高くなります。 誰かが時間をかけてパッチを作成したという事実は、 その機能に対する強い欲求を示しているため、 これは "Will it be useful?" と結びついています。 =back =begin original If you're on the list, you might hear the word "core" bandied around. It refers to the standard distribution. "Hacking on the core" means you're changing the C source code to the Perl interpreter. "A core module" is one that ships with Perl. =end original リストに参加している人は、あちこちで「コア」という言葉を 耳にするかもしれません。 これは標準配布を指しています。 「コアをハッキングする」とは、Perl インタプリタ のC ソースコードを 変更することを意味します。 「コアモジュール」とは、Perl に同梱されているモジュールです。 =head2 Keeping in sync (同期し続ける) =begin original The source code to the Perl interpreter, in its different versions, is kept in a repository managed by the git revision control system. The pumpkings and a few others have write access to the repository to check in changes. =end original 複数のバージョンの Perl インタプリタのソースコードは、 git リビジョン管理システムによって管理されるリポジトリに保存されています。 pumpking とその他の数人は、変更をチェックインするための リポジトリへの書き込みアクセス権を持っています。 =begin original How to clone and use the git perl repository is described in L. =end original git perl リポジトリを複製して使う方法は、L に 説明されています。 =begin original You can also choose to use rsync to get a copy of the current source tree for the bleadperl branch and all maintenance branches : =end original rsync を使って、bleadperlブランチとすべての保守ブランチの 現在のソースツリーのコピーを取得することもできます: $ rsync -avz rsync://perl5.git.perl.org/APC/perl-current . $ rsync -avz rsync://perl5.git.perl.org/APC/perl-5.10.x . $ rsync -avz rsync://perl5.git.perl.org/APC/perl-5.8.x . $ rsync -avz rsync://perl5.git.perl.org/APC/perl-5.6.x . $ rsync -avz rsync://perl5.git.perl.org/APC/perl-5.005xx . =begin original (Add the C<--delete> option to remove leftover files) =end original (残ったファイルを削除するために C<--delete> オプションを追加します) =begin original You may also want to subscribe to the perl5-changes mailing list to receive a copy of each patch that gets submitted to the maintenance and development "branches" of the perl repository. See http://lists.perl.org/ for subscription information. =end original perl5-changes メーリングリストに登録して、perl リポジトリーの保守および 開発「ブランチ」に送信される各パッチのコピーを受け取ることもできます。 登録のための情報については、http://lists.perl.org/ を参照してください。 =begin original If you are a member of the perl5-porters mailing list, it is a good thing to keep in touch with the most recent changes. If not only to verify if what you would have posted as a bug report isn't already solved in the most recent available perl development branch, also known as perl-current, bleading edge perl, bleedperl or bleadperl. =end original perl5-porters メーリングリストのメンバーであれば、最新の変更点を 把握しておくとよいでしょう。 バグレポートとして投稿したであろうものが、最新の perl 開発ブランチ (perl-current, leading edge perl, bleedperl, bleadperl としても 知られています)でまだ解決されていないかどうかを 確認するためだけではありません。 =begin original Needless to say, the source code in perl-current is usually in a perpetual state of evolution. You should expect it to be very buggy. Do B use it for any purpose other than testing and development. =end original 言うまでもなく、perl-current のソースコードは通常、永続的な進化の 状態にあります。 非常にバグが多いことを想定する必要があります。 テストと開発以外の目的では B<使わない> でください。 =head2 Perlbug administration (perlbug 管理) =begin original There is a single remote administrative interface for modifying bug status, category, open issues etc. using the B bugtracker system, maintained by Robert Spier. Become an administrator, and close any bugs you can get your sticky mitts on: =end original Robert Spier が管理する B バグトラッカーシステムを使って、 バグステータス、カテゴリ、未解決の問題などを変更するための単一の リモート管理インターフェイスがあります。 管理者になって、スティッキーミットで捕まえられるバグをすべて閉じてください: http://bugs.perl.org/ =begin original To email the bug system administrators: =end original バグシステム管理者に電子メールを送信するには: "perlbug-admin" =head2 Submitting patches (パッチを投稿する) =begin original Always submit patches to I. If you're patching a core module and there's an author listed, send the author a copy (see L). This lets other porters review your patch, which catches a surprising number of errors in patches. Please patch against the latest B version. (e.g., even if you're fixing a bug in the 5.8 track, patch against the C branch in the git repository.) =end original パッチは常に I に送信してください。 コアモジュールにパッチを適用していて、著者がリストされている場合は、その 著者にコピーを送信してください(L を参照してください)。 これにより、他の porters がパッチをレビューすることができ、パッチに驚くほど 多くのエラーが見つかります。 最新の B<開発> バージョンにパッチを当ててください (例えば、5.8 トラックのバグを修正している場合でも、git リポジトリの C ブランチにパッチを当ててください)。 =begin original If changes are accepted, they are applied to the development branch. Then the maintenance pumpking decides which of those patches is to be backported to the maint branch. Only patches that survive the heat of the development branch get applied to maintenance versions. =end original 変更が受け入れられた場合、それらは開発ブランチに適用されます。 次に、メンテナンスパンプキンが、それらのパッチのどれをメンテナンスブランチに バックポートするかを決定します。 開発ブランチの熱に耐えたパッチのみが、メンテナンス版に適用されます。 =begin original Your patch should update the documentation and test suite. See L. If you have added or removed files in the distribution, edit the MANIFEST file accordingly, sort the MANIFEST file using C, and include those changes as part of your patch. =end original パッチで文書とテストスイートを更新する必要があります。 L を参照してください。 ディストリビューションにファイルを追加または削除した場合は、 MANIFEST ファイルを適宜編集し、C を使って MANIFEST ファイルをソートし、それらの変更をパッチの一部として含めます。 =begin original Patching documentation also follows the same order: if accepted, a patch is first applied to B, and if relevant then it's backported to B. (With an exception for some patches that document behaviour that only appears in the maintenance branch, but which has changed in the development version.) =end original パッチの文書も同じ順序で作成されます: パッチが受け入れられた場合、 まず B に適用され、関連する場合は B に バックポートされます。 (例外として、メンテナンスブランチにのみ現れるけれども、 開発バージョンで変更されていいる振る舞いを 文書化するパッチがあります。) =begin original To report a bug in Perl, use the program I which comes with Perl (if you can't get Perl to work, send mail to the address I or I). Reporting bugs through I feeds into the automated bug-tracking system, access to which is provided through the web at http://rt.perl.org/rt3/ . It often pays to check the archives of the perl5-porters mailing list to see whether the bug you're reporting has been reported before, and if so whether it was considered a bug. See above for the location of the searchable archives. =end original Perl のバグを報告するには、Perl に付属のプログラム I を 使います(Perl を動作させることができない場合は、アドレス I または I にメールを送信してください)。 I を通じてバグを報告すると、自動バグ追跡システムにフィードされます; このシステムへのアクセスは http://rt.perl.org/rt3/ のウェブから 提供されています。 Perl5-porter メーリングリストのアーカイブをチェックして、 あなたが報告しているバグが以前に報告されたことがあるかどうか、 もしそうであれば、それがバグとみなされたかどうかを調べるとよいでしょう。 検索可能なアーカイブの場所については上記を参照してください。 =begin original The CPAN testers ( http://testers.cpan.org/ ) are a group of volunteers who test CPAN modules on a variety of platforms. Perl Smokers ( http://www.nntp.perl.org/group/perl.daily-build and http://www.nntp.perl.org/group/perl.daily-build.reports/ ) automatically test Perl source releases on platforms with various configurations. Both efforts welcome volunteers. In order to get involved in smoke testing of the perl itself visit L. In order to start smoke testing CPAN modules visit L or L or L. =end original CPAN testers (http://testers.cpan.org/) は、さまざまな プラットフォームで CPAN モジュールをテストするボランティアのグループです。 Perl Smoker ( http://www.nntp.perl.org/group/perl.daily-build と http://www.nntp.perl.org/group/perl.daily-build.reports/ ) は、 さまざまな構成のプラットフォームでPerlソースリリースを自動的にテストします。 どちらの取り組みもボランティアを歓迎しています。 Perl 自体のスモークテストに参加するには、 L を訪れてください。 CPAN モジュールのスモークテストを開始するには、 L または L または L を訪れてください。 =begin original It's a good idea to read and lurk for a while before chipping in. That way you'll get to see the dynamic of the conversations, learn the personalities of the players, and hopefully be better prepared to make a useful contribution when do you speak up. =end original 参加する前に、しばらくぶらぶらするのは良い考えです。 そうすれば、会話のダイナミックさを見ることができ、 プレーヤーの性格を知ることができ、うまくいけば、 あなたが発言したときに役に立つ貢献をするための準備が整うでしょう。 =begin original If after all this you still think you want to join the perl5-porters mailing list, send mail to I. To unsubscribe, send mail to I. =end original 以上のことを行ってもなお perl5-porters メーリングリストに 参加したいと思うなら、 I にメールを送ってください。 登録を解除するには、 I にメールを送ってください。 =begin original To hack on the Perl guts, you'll need to read the following things: =end original Perl の本質をハックするためには、以下を読む必要があります: =over 3 =item L =begin original This is of paramount importance, since it's the documentation of what goes where in the Perl source. Read it over a couple of times and it might start to make sense - don't worry if it doesn't yet, because the best way to study it is to read it in conjunction with poking at Perl source, and we'll do that later on. =end original これは、Perl ソースのどこに何があるかを記述した文書なので、非常に重要です。 この文書を何度か読んでみると、分かりはじめてくるかもしれませんが、 まだでも心配する必要はありません; なぜなら、この文書を学ぶ最善の方法は、Perl ソースを調べながら 読むことであり、これは後で行いますから。 =begin original Gisle Aas's "illustrated perlguts", also known as I, has very helpful pictures: =end original Gisle Aas の、 I としても知られる "illustrated perlguts" には、 とても役に立つ絵があります。 L =item L and L =begin original A working knowledge of XSUB programming is incredibly useful for core hacking; XSUBs use techniques drawn from the PP code, the portion of the guts that actually executes a Perl program. It's a lot gentler to learn those techniques from simple examples and explanation than from the core itself. =end original XSUB プログラミングの実用的な知識は、コアハッキングに非常に役立ちます; XSUBs では、Perl プログラムを実際に実行するコア部分である PP コードから引き出されたテクニックを使います。 これらのテクニックをコア自体から学ぶよりも、 簡単な例や説明から学ぶ方がはるかにやさしいです。 =item L =begin original The documentation for the Perl API explains what some of the internal functions do, as well as the many macros used in the source. =end original Perl API の文書では、内部関数の機能や、ソースで使われる多くのマクロについて 説明しています。 =item F =begin original This is a collection of words of wisdom for a Perl porter; some of it is only useful to the pumpkin holder, but most of it applies to anyone wanting to go about Perl development. =end original これは、Perl porters のための英知を集めたものです; その中にはパンプキンを持っている人にしか役に立たないものもありますが、 そのほとんどは Perl 開発を行おうとする人にも当てはまります。 =item The perl5-porters FAQ =begin original This should be available from http://dev.perl.org/perl5/docs/p5p-faq.html . It contains hints on reading perl5-porters, information on how perl5-porters works and how Perl development in general works. =end original http://dev.perl.org/perl5/docs/p5p-faq.html から入手できます。 perl5-porters を読むためのヒント、perl5-porters がどのように動作するか、 そして Perl 開発がどのように一般的に動作するかについての情報が 含まれています。 =back =head2 Finding Your Way Around (回避方法を見つける) =begin original Perl maintenance can be split into a number of areas, and certain people (pumpkins) will have responsibility for each area. These areas sometimes correspond to files or directories in the source kit. Among the areas are: =end original Perl の保守はいくつかの領域に分割することができ、それぞれの領域に対して 特定の人(パンプキン)が責任を持ちます。 これらの領域は、ソースキット内のファイルやディレクトリに対応する 場合があります。 次の領域があります: =over 3 =item Core modules (コアモジュール) =begin original Modules shipped as part of the Perl core live in various subdirectories, where two are dedicated to core-only modules, and two are for the dual-life modules which live on CPAN and may be maintained separately with respect to the Perl core: =end original Perl コアの一部として出荷されるモジュールは、様々なサブディレクトリにあります; 二つはコア専用モジュール用で、二つは二重管理モジュール用です; これは CPAN にあって、Perl コアとは独立して保守されているものです: lib/ is for pure-Perl modules, which exist in the core only. ext/ is for XS extensions, and modules with special Makefile.PL requirements, which exist in the core only. cpan/ is for dual-life modules, where the CPAN module is canonical (should be patched first). dist/ is for dual-life modules, where the blead source is canonical. =item Tests (テスト) =begin original There are tests for nearly all the modules, built-ins and major bits of functionality. Test files all have a .t suffix. Module tests live in the F and F directories next to the module being tested. Others live in F. See L =end original ほとんどすべてのモジュール、組み込み関数、主要な機能に対する テストがあります。 テストファイルにはすべて .t 拡張子が付いています。 モジュールテストは、テスト対象モジュールの隣の F ディレクトリと F ディレクトリにあります。 その他は F ディレクトリにあります。 L を参照してください。 =item Documentation (文書) =begin original Documentation maintenance includes looking after everything in the F directory, (as well as contributing new documentation) and the documentation to the modules in core. =end original 文書のメンテナンスには、F ディレクトリのすべての管理(新しい文書の 提供も含む)と、コアのモジュールへの文書が含まれます。 =item Configure =begin original The Configure process is the way we make Perl portable across the myriad of operating systems it supports. Responsibility for the Configure, build and installation process, as well as the overall portability of the core code rests with the Configure pumpkin - others help out with individual operating systems. =end original Configure プロセスは、Perl がサポートする無数のオペレーティングシステムに 対して Perl が移植性があるようにするための方法です。 Configure、構築、インストールプロセス、およびコアコードの全体的な 移植性に対する責任は、Configure パンプキンにあります - 他の人は個々のオペレーティングシステムを支援します。 =begin original The three files that fall under his/her responsibility are Configure, config_h.SH, and Porting/Glossary (and a whole bunch of small related files that are less important here). The Configure pumpkin decides how patches to these are dealt with. Currently, the Configure pumpkin will accept patches in most common formats, even directly to these files. Other committers are allowed to commit to these files under the strict condition that they will inform the Configure pumpkin, either on IRC (if he/she happens to be around) or through (personal) e-mail. =end original Configure パンプキンの責任下にある三つのファイルは Configure, config_h.SH, Porting/Glossary (およびこれらよりは重要でない、 大量の小さい関連ファイル) です。 Configure パンプキンはパッチをどのように扱うかを決定します。 現在の所、Configure パンプキンはほとんどの一般的な形式や、 それらのファイルを直接でも、受け入れています。 その他のコミッタは、(本人がいる) IRC または (個人の) 電子メールによって Configure パンプキンに知らせるという厳密な条件の下で これらのファイルのコミットを許されています。 =begin original The files involved are the operating system directories, (F, F, F and so on) the shell scripts which generate F and F, as well as the metaconfig files which generate F. (metaconfig isn't included in the core distribution.) =end original 関連するファイルは、オペレーティングシステムのディレクトリ (F, F, F など)、F と F を生成する シェルスクリプト、および F を生成する metaconfig ファイルです。 (metaconfig はコアディストリビューションには含まれていません。) =begin original See http://perl5.git.perl.org/metaconfig.git/blob/HEAD:/README for a description of the full process involved. =end original 関連する完全なプロセスに関する技術については http://perl5.git.perl.org/metaconfig.git/blob/HEAD:/README を 参照してください。 =item Interpreter (インタプリタ) =begin original And of course, there's the core of the Perl interpreter itself. Let's have a look at that in a little more detail. =end original もちろん、Perl インタプリタ自体の中核部分もあります。 これについてもう少し詳しく見てみましょう。 =back =begin original Before we leave looking at the layout, though, don't forget that F contains not only the file names in the Perl distribution, but short descriptions of what's in them, too. For an overview of the important files, try this: =end original レイアウトを見る前に、F には Perl 配布物のファイル名だけでなく、 その中にあるものの簡単な説明も含まれていることを忘れないでください。 重要なファイルの概要を知るには、以下を試してみてください: perl -lne 'print if /^[^\/]+\.[ch]\s+/' MANIFEST =head2 Elements of the interpreter (インタプリタの要素) =begin original The work of the interpreter has two main stages: compiling the code into the internal representation, or bytecode, and then executing it. L explains exactly how the compilation stage happens. =end original インタプリタの動作には二つの主要なステージがあります: コードを内部表現(バイトコード)にコンパイルし、それを実行します。 L は、コンパイルステージがどのように起こるかを 正確に説明しています。 =begin original Here is a short breakdown of perl's operation: =end original perl の操作について簡単に説明します: =over 3 =item Startup (開始) =begin original The action begins in F. (or F for miniperl) This is very high-level code, enough to fit on a single screen, and it resembles the code found in L; most of the real action takes place in F =end original アクションは F で始まります(miniperl の場合は F)。 これは非常に高レベルのコードで、一つの画面に収まります; また、L のコードに似ています; 実際のアクションのほとんどは F で行われます。 =begin original F is generated by L from F at make time, so you should make perl to follow this along. =end original F は L によって F から make 時に生成されますので、perl はこれに従うようにしてください。 =begin original First, F allocates some memory and constructs a Perl interpreter, along these lines: =end original まず、F はメモリを割り当て、次の行に従って Perl インタプリタを 構築します: 1 PERL_SYS_INIT3(&argc,&argv,&env); 2 3 if (!PL_do_undump) { 4 my_perl = perl_alloc(); 5 if (!my_perl) 6 exit(1); 7 perl_construct(my_perl); 8 PL_perl_destruct_level = 0; 9 } =begin original Line 1 is a macro, and its definition is dependent on your operating system. Line 3 references C, a global variable - all global variables in Perl start with C. This tells you whether the current running program was created with the C<-u> flag to perl and then F, which means it's going to be false in any sane context. =end original 1 行目はマクロで、その定義はオペレーティングシステムによって異なります。 3 行目はグローバル変数 C を参照しています; Perl のグローバル変数はすべて C で始まります。 これにより、現在実行中のプログラムが perl に対して C<-u> フラグを付けて 作成され、次に F フラグを付けて作成されたかどうかがわかります。 これは、まともなコンテキストでは偽になることを意味します。 =begin original Line 4 calls a function in F to allocate memory for a Perl interpreter. It's quite a simple function, and the guts of it looks like this: =end original 4 行目では、Perl インタプリタにメモリを割り当てるために F の関数を呼び出しています。 これは非常に単純な関数で、その中身は次のようになります: my_perl = (PerlInterpreter*)PerlMem_malloc(sizeof(PerlInterpreter)); =begin original Here you see an example of Perl's system abstraction, which we'll see later: C is either your system's C, or Perl's own C as defined in F if you selected that option at configure time. =end original C は、システムの C か、または F で 定義されている Perl 自身の C (設定時にこのオプションを選択した場合)の いずれかです。 =begin original Next, in line 7, we construct the interpreter using perl_construct, also in F; this sets up all the special variables that Perl needs, the stacks, and so on. =end original 次に、7 行目で、同じく F で perl_construct を使って インタプリタを作成します; これにより、Perl が必要とするすべての特殊変数やスタックなどが設定されます。 =begin original Now we pass Perl the command line options, and tell it to go: =end original 次に、Perl にコマンドラインオプションを渡し、実行するように指示します: exitstatus = perl_parse(my_perl, xs_init, argc, argv, (char **)NULL); if (!exitstatus) perl_run(my_perl); exitstatus = perl_destruct(my_perl); perl_free(my_perl); =begin original C is actually a wrapper around C, as defined in F, which processes the command line options, sets up any statically linked XS modules, opens the program and calls C to parse it. =end original C は実際には、F で定義されている C の ラッパーです; このラッパーはコマンドラインオプションを処理し、静的にリンクされた XS モジュールを設定し、プログラムを開き、C を 呼び出して構文解析します。 =item Parsing (パース) =begin original The aim of this stage is to take the Perl source, and turn it into an op tree. We'll see what one of those looks like later. Strictly speaking, there's three things going on here. =end original このステージの目的は、Perl ソースを取得し、それを op 木に変換することです。 これらのうちの一つがどのように見えるかについては、後で説明します。 厳密に言えば、ここでは三つのことが起こっています。 =begin original C, the parser, lives in F, although you're better off reading the original YACC input in F. (Yes, Virginia, there B a YACC grammar for Perl!) The job of the parser is to take your code and "understand" it, splitting it into sentences, deciding which operands go with which operators and so on. =end original パーサである C は F にありますが、 元の YACC 入力を F で読んだ方が良いでしょう。 (そう、バージニア、これが Perl のための YACC 文法です!)。 パーサの仕事は、コードを「理解」し、それを文に分割し、 どのオペランドがどの演算子と合うかなどを決定することです。 =begin original The parser is nobly assisted by the lexer, which chunks up your input into tokens, and decides what type of thing each token is: a variable name, an operator, a bareword, a subroutine, a core function, and so on. The main point of entry to the lexer is C, and that and its associated routines can be found in F. Perl isn't much like other computer languages; it's highly context sensitive at times, it can be tricky to work out what sort of token something is, or where a token ends. As such, there's a lot of interplay between the tokeniser and the parser, which can get pretty frightening if you're not used to it. =end original パーサは字句解析器の支援を受けます; 字句解析器は入力をトークンに分割し、変数名、演算子、裸の単語、サブルーチン、 コア関数など、各トークンがどのような種類のものであるかを判断します。 字句解析器への主なエントリポイントは C です; 字句解析器とそれに関連するルーチンは F にあります。 Perl は他のコンピュータ言語とはあまり似ていません; コンテキストに非常に敏感な場合があり、トークンがどのような種類の ものであるか、トークンがどこで終わるかを理解するのは難しい場合があります。 そのため、トークン解析器とパーサの間には多くの相互作用があり、 これに慣れていないと非常に恐ろしくなります。 =begin original As the parser understands a Perl program, it builds up a tree of operations for the interpreter to perform during execution. The routines which construct and link together the various operations are to be found in F, and will be examined later. =end original パーサは Perl プログラムを理解すると、実行中にインタプリタが 実行するための操作木を構築します。 さまざまな操作を構築してリンクするルーチンは Fにあり、 これは後で検討します。 =item Optimization (最適化) =begin original Now the parsing stage is complete, and the finished tree represents the operations that the Perl interpreter needs to perform to execute our program. Next, Perl does a dry run over the tree looking for optimisations: constant expressions such as C<3 + 4> will be computed now, and the optimizer will also see if any multiple operations can be replaced with a single one. For instance, to fetch the variable C<$foo>, instead of grabbing the glob C<*foo> and looking at the scalar component, the optimizer fiddles the op tree to use a function which directly looks up the scalar in question. The main optimizer is C in F, and many ops have their own optimizing functions. =end original これで構文解析段階が完了し、完成した木は Perl インタプリタが プログラムを実行するために実行する必要のある操作を表します。 次に、Perl は木を仮ここで走査して最適化を探します: C<3 + 4> のような定数式はここで計算され、オプティマイザは複数の操作が 単一の操作に置き換えられるかどうかも調べます。 例えば、変数 C<$foo> をフェッチするために、glob C<*foo> を取得して スカラ成分を調べる代わりに、オプティマイザは、問題のスカラを 直接検索する関数を使うように op 木を操作します。 メインオプティマイザは F の C であり、多くの op は 独自の最適化関数を持っています。 =item Running (実行) =begin original Now we're finally ready to go: we have compiled Perl byte code, and all that's left to do is run it. The actual execution is done by the C function in F; more specifically, it's done by these three innocent looking lines: =end original Perl バイトコードをコンパイルし、あとはそれを実行するだけです。 実際の実行は、F の C 関数によって行われます; 具体的には、次の三つの無邪気に見える行によって行われます: while ((PL_op = CALL_FPTR(PL_op->op_ppaddr)(aTHX))) { PERL_ASYNC_CHECK(); } =begin original You may be more comfortable with the Perl version of that: =end original 次のような Perl バージョンの方が使いやすいかもしれません: PERL_ASYNC_CHECK() while $Perl::op = &{$Perl::op->{function}}; =begin original Well, maybe not. Anyway, each op contains a function pointer, which stipulates the function which will actually carry out the operation. This function will return the next op in the sequence - this allows for things like C which choose the next op dynamically at run time. The C makes sure that things like signals interrupt execution if required. =end original ええと、違うかも知れません。 とにかく、各 op には関数ポインタが含まれていて、実際に操作を実行する関数を 指定します。 この関数は、シーケンス内の次の op を返します - これにより、 C のようなものが実行時に動的に次の op を選択することができます。 C は、シグナルのようなものが必要に応じて実行を 中断するようにします。 =begin original The actual functions called are known as PP code, and they're spread between four files: F contains the "hot" code, which is most often used and highly optimized, F contains all the system-specific functions, F contains the functions which implement control structures (C, C and the like) and F contains everything else. These are, if you like, the C code for Perl's built-in functions and operators. =end original 実際に呼び出される関数は PP コードと呼ばれ、四つのファイルに分散されます。 F には最も頻繁に使われ高度に最適化された "hot"コードが含まれ、 F にはシステム固有の関数がすべて含まれ、 F には制御構造を実装する関数(C、C など)が含まれ、 Fにはその他のすべてが含まれます。 これらは、言ってみれば、Perl の組み込み関数と演算子の C コードです。 =begin original Note that each C function is expected to return a pointer to the next op. Calls to perl subs (and eval blocks) are handled within the same runops loop, and do not consume extra space on the C stack. For example, C and C just push a C or C block struct onto the context stack which contain the address of the op following the sub call or eval. They then return the first op of that sub or eval block, and so execution continues of that sub or block. Later, a C or C op pops the C or C, retrieves the return op from it, and returns it. =end original 各 C 関数は、次の op へのポインタを返すことが期待されていることに 注意してください。 perl サブルーチン (および eval ブロック)への呼び出しは、同じ runops ループ内で処理され、C スタック上の余分なスペースを消費しません。 たとえば、C と C は、 C または C ブロック構造体を、サブルーチン呼び出しまたは eval に続く op のアドレスを含むコンテキストスタックにプッシュします。 次に、それらはそのサブルーチンまたは eval ブロックの最初の op を返すので、 そのサブルーチンまたはブロックの実行が継続されます。 その後、C または C op が C または C をポップし、そこから return op を取得して返します。 =item Exception handing (例外処理) =begin original Perl's exception handing (i.e. C etc.) is built on top of the low-level C/C C-library functions. These basically provide a way to capture the current PC and SP registers and later restore them; i.e. a C continues at the point in code where a previous C was done, with anything further up on the C stack being lost. This is why code should always save values using C rather than in auto variables. =end original Perl の例外処理(C など)は、低レベルの C/C C ライブラリ関数の上に構築されています。 これらは基本的に、現在の PC と SP レジスタを取得し、後で復元する方法を 提供します; つまり、C は、コード内で前の C が実行された時点で 継続され、C スタック上の上位のものは失われます。 これが、コードが常に自動変数ではなく C を使って 値を保存すべき理由です。 =begin original The perl core wraps C etc in the macros C and C. The basic rule of perl exceptions is that C, and C (in the absence of C) perform a C, while C within C does a C. =end original perl コアは、マクロ C と C で C などをラップします。 perl 例外の基本的なルールは、C と C(C がない場合)は C を実行し、C 内の C は C を 実行するということです。 =begin original At entry points to perl, such as C, C and C each does a C, then enter a runops loop or whatever, and handle possible exception returns. For a 2 return, final cleanup is performed, such as popping stacks and calling C or C blocks. Amongst other things, this is how scope cleanup still occurs during an C. =end original C, C, C などの perl へのエントリポイントでは、それぞれ C を実行し、 runops ループなどに入り、考えられる例外リターンを処理します。 2 リターンの場合は、スタックをポップしたり、C または C ブロックを呼び出すなど、最終的なクリーンアップが実行されます。 とりわけ、C の実行中にスコープのクリーンアップが行われる方法は このようになっています。 =begin original If a C can find a C block on the context stack, then the stack is popped to that level and the return op in that block is assigned to C; then a C is performed. This normally passes control back to the guard. In the case of C and C, a non-null C triggers re-entry to the runops loop. The is the normal way that C or C is handled within an C. =end original C がコンテキストスタック上に C ブロックを見つけることが できる場合、スタックはそのレベルにポップされ、そのブロック内の return op が C に割り当てられます; 次に C が実行されます。 これにより、通常は制御がガードに戻されます。 C と C の場合、非 NULL の C が runops ループへの再エントリを引き起こします。 これは、C 内で C または C を処理する通常の方法です。 =begin original Sometimes ops are executed within an inner runops loop, such as tie, sort or overload code. In this case, something like =end original 内部 runops ループ(tie、sort、overload コードなど)内で op が 実行されることがあります。 この場合、以下のようになります: sub FETCH { eval { die } } =begin original would cause a longjmp right back to the guard in C, popping both runops loops, which is clearly incorrect. One way to avoid this is for the tie code to do a C before executing C in the inner runops loop, but for efficiency reasons, perl in fact just sets a flag, using C. The C, C and C ops check this flag, and if true, they call C, which does a C and starts a new runops level to execute the code, rather than doing it on the current loop. =end original これは、C のガードに対して longjmp を引き起こし、両方の runops ループをポップさせますが、これは明らかに正しくありません。 これを回避する一つの方法は、内部 runops ループで C を実行する前に、 tie コードが C を実行することですが、効率性の理由から、 perl は実際には C を使ってフラグを設定するだけです。 C, C, C op はこのフラグをチェックし、 真の場合は C を呼び出します; これは C を実行し、新しい runops レベルを開始して コードを実行します; 現在のループでは実行されません。 =begin original As a further optimisation, on exit from the eval block in the C, execution of the code following the block is still carried on in the inner loop. When an exception is raised, C compares the C level of the C with C and if they differ, just re-throws the exception. In this way any inner loops get popped. =end original さらなる最適化として、C の eval ブロックを終了すると、 ブロックに続くコードの実行は依然として内側のループで実行されます。 例外が発生すると、C は C の C レベルと C を比較し、両者が異なる場合は例外を再スローします。 このようにして、内側のループはポップされます。 =begin original Here's an example. =end original 以下は例です: 1: eval { tie @a, 'A' }; 2: sub A::TIEARRAY { 3: eval { die }; 4: die; 5: } =begin original To run this code, C is called, which does a C then enters a runops loop. This loop executes the eval and tie ops on line 1, with the eval pushing a C onto the context stack. =end original このコードを実行するために、C が呼び出され、C を 実行して runops ループに入ります。 このループは 1 行目の eval と tie op を実行します; eval は C をコンテキストスタックにプッシュします。 =begin original The C does a C, then starts a second runops loop to execute the body of C. When it executes the entertry op on line 3, C is true, so C calls C which does a C and starts a third runops loop, which then executes the die op. At this point the C call stack looks like this: =end original C は C を実行し、2 番目の runops ループを開始して C の本体を実行します。 3 行目の entertry op を実行すると、C は真であるため、 C は C を呼び出して C を実行し、 3 番目の runops ループを開始して die op を実行します。 この時点で、C コールスタックは次のようになります。 Perl_pp_die Perl_runops # third loop S_docatch_body S_docatch Perl_pp_entertry Perl_runops # second loop S_call_body Perl_call_sv Perl_pp_tie Perl_runops # first loop S_run_body perl_run main =begin original and the context and data stacks, as shown by C<-Dstv>, look like: =end original コンテキストスタックとデータスタックは、C<-Dstv> で示すように、 次のようになります: STACK 0: MAIN CX 0: BLOCK => CX 1: EVAL => AV() PV("A"\0) retop=leave STACK 1: MAGIC CX 0: SUB => retop=(null) CX 1: EVAL => * retop=nextstate =begin original The die pops the first C off the context stack, sets C from it, does a C, and control returns to the top C. This then starts another third-level runops level, which executes the nextstate, pushmark and die ops on line 4. At the point that the second C is called, the C call stack looks exactly like that above, even though we are no longer within an inner eval; this is because of the optimization mentioned earlier. However, the context stack now looks like this, ie with the top CxEVAL popped: =end original die はコンテキストスタックから最初の C をポップし、そこから C をセットし、C を実行し、制御はトップの C に戻ります。 これにより、もう一つの第 3 レベルの runops レベルが開始され、 4 行目の nextstate、pushmark、die ops が実行されます。 2 番目の C が呼び出された時点で、C のコールスタックは上記と まったく同じように見えますが、内側の eval 内ではありません; これは前述の最適化のためです。 しかし、コンテキストスタックは次のように見えます; つまり、トップ CxEVAL がポップされます: STACK 0: MAIN CX 0: BLOCK => CX 1: EVAL => AV() PV("A"\0) retop=leave STACK 1: MAGIC CX 0: SUB => retop=(null) =begin original The die on line 4 pops the context stack back down to the CxEVAL, leaving it as: =end original 4 行目の die は、コンテキストスタックを CxEVAL にポップダウンし、 次のように残します: STACK 0: MAIN CX 0: BLOCK => =begin original As usual, C is extracted from the C, and a C done, which pops the C stack back to the docatch: =end original いつものように、C から C が抽出され、 C が実行されて C スタックが docatch に戻されます: S_docatch Perl_pp_entertry Perl_runops # second loop S_call_body Perl_call_sv Perl_pp_tie Perl_runops # first loop S_run_body perl_run main =begin original In this case, because the C level recorded in the C differs from the current one, C just does a C and the C stack unwinds to: =end original この場合、C に記録されている C レベルが現在のレベルと 異なるため、C は C を実行し、C スタックは 以下のように巻き戻します: perl_run main =begin original Because C is non-null, C starts a new runops loop and execution continues. =end original C は NULL でないため、C は新しい runops ループを 開始し、実行が継続されます。 =back =head2 Internal Variable Types (内部変数型) =begin original You should by now have had a look at L, which tells you about Perl's internal variable types: SVs, HVs, AVs and the rest. If not, do that now. =end original L を見ると、Perl の内部変数型(SV、HV、AVなど)について 知ることができます。 そうでない場合は、今すぐ見てください。 =begin original These variables are used not only to represent Perl-space variables, but also any constants in the code, as well as some structures completely internal to Perl. The symbol table, for instance, is an ordinary Perl hash. Your code is represented by an SV as it's read into the parser; any program files you call are opened via ordinary Perl filehandles, and so on. =end original これらの変数は、Perl スペース変数だけでなく、コード内の任意の定数や、 完全に Perl 内部の構造体を表すためにも使われます。 例えば、シンボルテーブルは通常の Perl ハッシュです。 コードはパーサに読み込まれるときに SV によって表されます; 呼び出したプログラムファイルは通常の Perl ファイルハンドルを 介して開かれます; といったことです。 =begin original The core L module lets us examine SVs from a Perl program. Let's see, for instance, how Perl treats the constant C<"hello">. =end original コア L モジュールを使うと、Perl プログラムから SV を調べることができます。 例えば、Perl が定数 C<"hello"> をどのように処理するかを見てみましょう。 % perl -MDevel::Peek -e 'Dump("hello")' 1 SV = PV(0xa041450) at 0xa04ecbc 2 REFCNT = 1 3 FLAGS = (POK,READONLY,pPOK) 4 PV = 0xa0484e0 "hello"\0 5 CUR = 5 6 LEN = 6 =begin original Reading C output takes a bit of practise, so let's go through it line by line. =end original C の出力を読むには少し練習が必要なので、1 行ずつ 見ていきましょう。 =begin original Line 1 tells us we're looking at an SV which lives at C<0xa04ecbc> in memory. SVs themselves are very simple structures, but they contain a pointer to a more complex structure. In this case, it's a PV, a structure which holds a string value, at location C<0xa041450>. Line 2 is the reference count; there are no other references to this data, so it's 1. =end original 1 行目は、メモリ内の C<0xa04ecbc> に存在する SV を見ていることを示しています。 SV 自体は非常に単純な構造ですが、より複雑な構造へのポインタを含んでいます。 この場合は、それは PV で、場所 C<0xa041450> にある文字列値を保持する構造です。 2 行目は参照カウントです; このデータへの他の参照はないので 1 です。 =begin original Line 3 are the flags for this SV - it's OK to use it as a PV, it's a read-only SV (because it's a constant) and the data is a PV internally. Next we've got the contents of the string, starting at location C<0xa0484e0>. =end original 3 行目はこの SV のフラグです - これをPVとして使っても問題ありません; これは読み取り専用の SV (定数であるため)であり、データは内部的に PV です。 次に、位置 C<0xa0484e0> から始まる文字列の内容を取得します。 =begin original Line 5 gives us the current length of the string - note that this does B include the null terminator. Line 6 is not the length of the string, but the length of the currently allocated buffer; as the string grows, Perl automatically extends the available storage via a routine called C. =end original 5 行目は、文字列の現在の長さを示しています - これは ヌル終端文字が含まれて B<いない> ことに注意してください。 6 行目は文字列の長さではなく、現在割り当てられているバッファの長さです; 文字列が大きくなると、Perl は自動的に C というルーチンを使って 利用可能な記憶域を拡張します。 =begin original You can get at any of these quantities from C very easily; just add C to the name of the field shown in the snippet, and you've got a macro which will return the value: C returns the current length of the string, C returns the reference count, C returns the string itself with its length, and so on. More macros to manipulate these properties can be found in L. =end original これらの値は C から非常に簡単に得ることができます; スニペットに示されているフィールドの名前に C を追加するだけで、 その値を返すマクロができます: C は文字列の現在の長さを返し、C は 参照カウントを返し、C は文字列そのものとその長さを返します。 これらのプロパティを操作するもっと多くのマクロは L にあります。 =begin original Let's take an example of manipulating a PV, from C, in F =end original F の C から PV を操作する例を見てみましょう。 1 void 2 Perl_sv_catpvn(pTHX_ register SV *sv, register const char *ptr, register STRLEN len) 3 { 4 STRLEN tlen; 5 char *junk; 6 junk = SvPV_force(sv, tlen); 7 SvGROW(sv, tlen + len + 1); 8 if (ptr == junk) 9 ptr = SvPVX(sv); 10 Move(ptr,SvPVX(sv)+tlen,len,char); 11 SvCUR(sv) += len; 12 *SvEND(sv) = '\0'; 13 (void)SvPOK_only_UTF8(sv); /* validate pointer */ 14 SvTAINT(sv); 15 } =begin original This is a function which adds a string, C, of length C onto the end of the PV stored in C. The first thing we do in line 6 is make sure that the SV B a valid PV, by calling the C macro to force a PV. As a side effect, C gets set to the current value of the PV, and the PV itself is returned to C. =end original これは、長さ C の文字列 C を、C に保存されている PV の末尾に 追加する関数です。 6 行目で最初に行うことは、C マクロを呼び出して PV を 強制することによって、SV が有効な PV を B<持っている> ことを確認することです。 副作用として、C は PV の現在の値に設定され、PV 自体は C に 戻されます。 =begin original In line 7, we make sure that the SV will have enough room to accommodate the old string, the new string and the null terminator. If C isn't big enough, C will reallocate space for us. =end original 7 行目では、SV に古い文字列、新しい文字列、ヌルターミネータを収容する 十分なスペースがあることを確認しています。 C が十分に大きくない場合は、C がスペースを再割り当てします。 =begin original Now, if C is the same as the string we're trying to add, we can grab the string directly from the SV; C is the address of the PV in the SV. =end original C が追加しようとしている文字列と同じであれば、その文字列を SV から 直接取得できます; C は SV 内の PV のアドレスです。 =begin original Line 10 does the actual catenation: the C macro moves a chunk of memory around: we move the string C to the end of the PV - that's the start of the PV plus its current length. We're moving C bytes of type C. After doing so, we need to tell Perl we've extended the string, by altering C to reflect the new length. C is a macro which gives us the end of the string, so that needs to be a C<"\0">. =end original 10 行目で実際の結合が行われます: C マクロはメモリの塊を移動します: 文字列 C を PV の末尾に移動します - これは PV の先頭に現在の長さを加えたものです。 C 型の C バイトを移動します。 その後、新しい長さを反映するように C を変更して文字列を拡張したことを Perl に伝える必要があります。 C は文字列の末尾を与えるマクロなので、C<"\0"> である必要があります。 =begin original Line 13 manipulates the flags; since we've changed the PV, any IV or NV values will no longer be valid: if we have C<$a=10; $a.="6";> we don't want to use the old IV of 10. C is a special UTF-8-aware version of C, a macro which turns off the IOK and NOK flags and turns on POK. The final C is a macro which launders tainted data if taint mode is turned on. =end original 13 行目はフラグを操作します; PV を変更したため、IV や NV の値は無効になります: C<$a=10; $a.="6";> があれば、古い IV の 10 は使いたくありません。 C は C の特別な UTF-8 対応バージョンで、 IOK と NOK フラグをオフにし、POK をオンにするマクロです。 最後の C は、汚染チェックモードがオンになっていれば、汚染された データを洗浄するマクロです。 =begin original AVs and HVs are more complicated, but SVs are by far the most common variable type being thrown around. Having seen something of how we manipulate these, let's go on and look at how the op tree is constructed. =end original AV と HV はもっと複雑ですが、SV は群を抜いて最も一般的な変数型です。 これらを操作する方法を見てきたので、次に op 木がどのように構築されるかを 見ていきましょう。 =head2 Op Trees (op 木) =begin original First, what is the op tree, anyway? The op tree is the parsed representation of your program, as we saw in our section on parsing, and it's the sequence of operations that Perl goes through to execute your program, as we saw in L. =end original まず、op 木とは何でしょうか? op 木は、構文解析のセクションで説明したように、プログラムを構文解析した 表現であり、L で説明したように、Perl がプログラムを実行するために 行う一連の操作です。 =begin original An op is a fundamental operation that Perl can perform: all the built-in functions and operators are ops, and there are a series of ops which deal with concepts the interpreter needs internally - entering and leaving a block, ending a statement, fetching a variable, and so on. =end original op は Perl が実行できる基本的な操作です: すべての組み込み関数と演算子は op であり、ブロックの出入り、文の 終了、変数のフェッチなど、インタプリタが内部的に必要とする概念を処理する 一連の op があります。 =begin original The op tree is connected in two ways: you can imagine that there are two "routes" through it, two orders in which you can traverse the tree. First, parse order reflects how the parser understood the code, and secondly, execution order tells perl what order to perform the operations in. =end original op 木は二つの方法で接続されています: op 木には二つの「ルート」があり、ツリーをトラバースできる二つの 順序があると想像できます。 第 1 に、構文解析順序はパーサがコードをどのように理解したかを反映し、 第 2 に、実行順序は perl に操作を実行する順序を指示します。 =begin original The easiest way to examine the op tree is to stop Perl after it has finished parsing, and get it to dump out the tree. This is exactly what the compiler backends L, L and L do. =end original op 木を調べる最も簡単な方法は、Perl が構文解析を完了した後で Perl を停止し、 Perl に木をダンプさせることです。 これはまさに、コンパイラのバックエンド L、 L、L が行うことです。 =begin original Let's have a look at how Perl sees C<$a = $b + $c>: =end original Perl が C<$a = $b + $c> をどのように見るかを見てみましょう。 % perl -MO=Terse -e '$a=$b+$c' 1 LISTOP (0x8179888) leave 2 OP (0x81798b0) enter 3 COP (0x8179850) nextstate 4 BINOP (0x8179828) sassign 5 BINOP (0x8179800) add [1] 6 UNOP (0x81796e0) null [15] 7 SVOP (0x80fafe0) gvsv GV (0x80fa4cc) *b 8 UNOP (0x81797e0) null [15] 9 SVOP (0x8179700) gvsv GV (0x80efeb0) *c 10 UNOP (0x816b4f0) null [15] 11 SVOP (0x816dcf0) gvsv GV (0x80fa460) *a =begin original Let's start in the middle, at line 4. This is a BINOP, a binary operator, which is at location C<0x8179828>. The specific operator in question is C - scalar assignment - and you can find the code which implements it in the function C in F. As a binary operator, it has two children: the add operator, providing the result of C<$b+$c>, is uppermost on line 5, and the left hand side is on line 10. =end original 真ん中の 4 行目から始めましょう。 これは BINOP (二項演算子)で、位置 C<0x8179828> にあります。 問題となっている特定の演算子は C - スカラ代入 - です; この演算子を実装するコードは、F の関数 C にあります。 二項演算子としては二つの子があります: C<$b+$c> の結果を与える加算演算子は 5 行目の一番上にあり、左側は 10 行目にあります。 =begin original Line 10 is the null op: this does exactly nothing. What is that doing there? If you see the null op, it's a sign that something has been optimized away after parsing. As we mentioned in L, the optimization stage sometimes converts two operations into one, for example when fetching a scalar variable. When this happens, instead of rewriting the op tree and cleaning up the dangling pointers, it's easier just to replace the redundant operation with the null op. Originally, the tree would have looked like this: =end original 10 行目は null op です: これは何もしません。 そこで何をしているのでしょう? null op が表示された場合は、解析後に何かが最適化されたことを示しています。 L で説明したように、最適化ステージでは、スカラ変数を フェッチする場合など、二つの演算が一つに変換されることがあります。 このような場合は、op 木を書き直して相手がいないポインタを クリーンアップする代わりに、冗長な演算を null op に置き換える方が簡単です。 本来、木は次のように表示されます: 10 SVOP (0x816b4f0) rv2sv [15] 11 SVOP (0x816dcf0) gv GV (0x80fa460) *a =begin original That is, fetch the C entry from the main symbol table, and then look at the scalar component of it: C (C into F) happens to do both these things. =end original つまり、メインシンボルテーブルから C エントリを取得し、その スカラコンポーネントを調べます: C(F の C)は、これらの両方を実行します。 =begin original The right hand side, starting at line 5 is similar to what we've just seen: we have the C op (C also in F) add together two Cs. =end original 5 行目から始まる右側は、先ほど見たものと似ています: C op (C も F にあります) が二つの C を 加算します。 =begin original Now, what's this about? =end original ここで、これは何でしょう? 1 LISTOP (0x8179888) leave 2 OP (0x81798b0) enter 3 COP (0x8179850) nextstate =begin original C and C are scoping ops, and their job is to perform any housekeeping every time you enter and leave a block: lexical variables are tidied up, unreferenced variables are destroyed, and so on. Every program will have those first three lines: C is a list, and its children are all the statements in the block. Statements are delimited by C, so a block is a collection of C ops, with the ops to be performed for each statement being the children of C. C is a single op which functions as a marker. =end original C と C はスコープ op であり、それらの仕事は、ブロックに 入ったり出たりするたびにハウスキーピングを実行することです: レキシカル変数は整理され、参照されていない変数は破棄され、などです。 すべてのプログラムには最初の 3 行があります: C はリストであり、その子はブロック内のすべての文です。 文は C で区切られているため、ブロックは C op の集合であり、各文に対して実行される op は C の子となります。 C はマーカーとして機能する単一の op です。 =begin original That's how Perl parsed the program, from top to bottom: =end original このようにして、Perl はプログラムを上から下まで構文解析しました: Program | Statement | = / \ / \ $a + / \ $b $c =begin original However, it's impossible to B the operations in this order: you have to find the values of C<$b> and C<$c> before you add them together, for instance. So, the other thread that runs through the op tree is the execution order: each op has a field C which points to the next op to be run, so following these pointers tells us how perl executes the code. We can traverse the tree in this order using the C option to C: =end original しかし、この順序で操作を B<実行> することは不可能です: 例えば、C<$b> と C<$c> の値を見つけてから、それらを一緒に追加する 必要があります。 そのため、op 木を通るもう一つの糸は実行順序です: 各 op には、次に実行される op を指すフィールド C があるので、 これらのポインタに従って perl がどのようにコードを実行するかを 知ることができます。 C オプションを C に指定すると、この順序で木を走査できます: % perl -MO=Terse,exec -e '$a=$b+$c' 1 OP (0x8179928) enter 2 COP (0x81798c8) nextstate 3 SVOP (0x81796c8) gvsv GV (0x80fa4d4) *b 4 SVOP (0x8179798) gvsv GV (0x80efeb0) *c 5 BINOP (0x8179878) add [1] 6 SVOP (0x816dd38) gvsv GV (0x80fa468) *a 7 BINOP (0x81798a0) sassign 8 LISTOP (0x8179900) leave =begin original This probably makes more sense for a human: enter a block, start a statement. Get the values of C<$b> and C<$c>, and add them together. Find C<$a>, and assign one to the other. Then leave. =end original これはおそらく人間にとってより分かりやすいでしょう: ブロックにを入り、文を開始します。 C<$b> と C<$c> の値を取得し、それらを加算します。 C<$a> を検索し、一方をもう一方に代入します。 そして離れます。 =begin original The way Perl builds up these op trees in the parsing process can be unravelled by examining F, the YACC grammar. Let's take the piece we need to construct the tree for C<$a = $b + $c> =end original Perl が構文解析プロセスでこれらの op 木を構築する方法は、YACC 文法である F を調べることによって解明できます。 C<$a = $b + $c> の木を構築するために必要な部分を取り上げましょう: 1 term : term ASSIGNOP term 2 { $$ = newASSIGNOP(OPf_STACKED, $1, $2, $3); } 3 | term ADDOP term 4 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } =begin original If you're not used to reading BNF grammars, this is how it works: You're fed certain things by the tokeniser, which generally end up in upper case. Here, C, is provided when the tokeniser sees C<+> in your code. C is provided when C<=> is used for assigning. These are "terminal symbols", because you can't get any simpler than them. =end original BNF 文法を読むことに慣れていない人は、次のように動作します: ある種のものをトークナイザによって供給されます; それは通常大文字になります。 ここでは、C は、トークナイザがコード内で C<+> が検出したときに 提供されます。 C は、代入のために C<=> が使われたときに提供されます。 これらは「終端記号」です; これ以上単純なものは得られないからです。 =begin original The grammar, lines one and three of the snippet above, tells you how to build up more complex forms. These complex forms, "non-terminal symbols" are generally placed in lower case. C here is a non-terminal symbol, representing a single expression. =end original 上のスニペットの1 行目と3 行目の文法では、より複雑な形式を 構築する方法が説明されています。 これらの複合形式である「非終端記号」は、通常は小文字で配置されます。 ここで C は、単一の式を表す非終端記号です。 =begin original The grammar gives you the following rule: you can make the thing on the left of the colon if you see all the things on the right in sequence. This is called a "reduction", and the aim of parsing is to completely reduce the input. There are several different ways you can perform a reduction, separated by vertical bars: so, C followed by C<=> followed by C makes a C, and C followed by C<+> followed by C can also make a C. =end original 文法は次の規則を与えます: 右側のすべてのものを順番に見れば、 コロンの左側のものを作ることができます。 これは「還元」(reduction)と呼ばれ、構文解析の目的は入力を完全に 還元することです。 還元を実行するにはいくつかの異なる方法があり、縦棒で区切られています: つまり、C の後に C<=> と C が続くと C を作成し、 C の後に C<+> と C が続いても C を作成できます。 =begin original So, if you see two terms with an C<=> or C<+>, between them, you can turn them into a single expression. When you do this, you execute the code in the block on the next line: if you see C<=>, you'll do the code in line 2. If you see C<+>, you'll do the code in line 4. It's this code which contributes to the op tree. =end original それで、二つの項の間に C<=> または C<+> がある場合、それらを一つの式に 変換できます。 これを行うときは、次の行のブロック内のコードを実行します: C<=> がある場合は 2 行目のコードを実行します。 C<+> がある場合は 4 行目のコードを実行します。 このコードが op 木に貢献しています。 | term ADDOP term { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } =begin original What this does is creates a new binary op, and feeds it a number of variables. The variables refer to the tokens: C<$1> is the first token in the input, C<$2> the second, and so on - think regular expression backreferences. C<$$> is the op returned from this reduction. So, we call C to create a new binary operator. The first parameter to C, a function in F, is the op type. It's an addition operator, so we want the type to be C. We could specify this directly, but it's right there as the second token in the input, so we use C<$2>. The second parameter is the op's flags: 0 means "nothing special". Then the things to add: the left and right hand side of our expression, in scalar context. =end original これにより、新しいバイナリ op が作成され、多数の変数が渡されます。 変数はトークンを参照します: C<$1> は入力の最初のトークン、C<$2> は 2 番目のトークン、という形です - 正規表現の後方参照を考えてみてください。 C<$$> はこの還元から返される op です。 そこで、C を呼び出して新しい二項演算子を作成します。 F にある関数である C の最初の引数は op 型です。 これは加算演算子なので、型が C になってほしいです。 これを直接指定することもできますが、これは入力の 2 番目のトークンとして すぐそこにあるので、C<$2> を使います。 2 番目の引数は op のフラグです: 0 は「特別なものがない」ことを意味します。 次に追加すべきものは、スカラコンテキストでの式の左辺と右辺です。 =head2 Stacks (スタック) =begin original When perl executes something like C, how does it pass on its results to the next op? The answer is, through the use of stacks. Perl has a number of stacks to store things it's currently working on, and we'll look at the three most important ones here. =end original perl が C のようなものを実行した場合、その結果をどのように 次の op に渡すのでしょうか? 答えは、スタックを使うことです。 Perl には、現在作業中のものを保存するためのスタックが数多くありますが、 ここでは最も重要な三つのスタックについて説明します。 =over 3 =item Argument stack (引数スタック) =begin original Arguments are passed to PP code and returned from PP code using the argument stack, C. The typical way to handle arguments is to pop them off the stack, deal with them how you wish, and then push the result back onto the stack. This is how, for instance, the cosine operator works: =end original 引数は PP コードに渡され、引数スタック C を使って PP コードから 返されます。 引数を処理する一般的な方法は、引数をスタックから取り出し、 必要に応じて処理した後、結果をスタックにプッシュします。 たとえば、余弦演算子は次のように動作します: NV value; value = POPn; value = Perl_cos(value); XPUSHn(value); =begin original We'll see a more tricky example of this when we consider Perl's macros below. C gives you the NV (floating point value) of the top SV on the stack: the C<$x> in C. Then we compute the cosine, and push the result back as an NV. The C in C means that the stack should be extended if necessary - it can't be necessary here, because we know there's room for one more item on the stack, since we've just removed one! The C macros at least guarantee safety. =end original 以下に示す Perl のマクロを考えると、もっと巧妙な例を見ることになります。 C はスタック上の最上位 SV の NV (浮動小数点値)を与えます: C の C<$x> です。 次にコサインを計算し、その結果を NV としてプッシュします。 C の C は、必要に応じてスタックを拡張する 必要があることを意味します - ここでは必要ありません; なぜなら、スタック上にもう一つの項目のためのスペースがあることが わかっているからです; なぜなら、一つを削除したばかりなのです! C マクロは少なくとも安全性を保証します。 =begin original Alternatively, you can fiddle with the stack directly: C gives you the first element in your portion of the stack, and C gives you the top SV/IV/NV/etc. on the stack. So, for instance, to do unary negation of an integer: =end original あるいは、スタックを直接操作することもできます: C は スタックのあなたの部分の最初の要素を与え、C はスタック上の最上位の SV/IV/NV などを与えます。 たとえば、整数の単項否定を行うには、次のようにします: SETi(-TOPi); =begin original Just set the integer value of the top stack entry to its negation. =end original 最上位スタックエントリの整数値をその否定に設定するだけです。 =begin original Argument stack manipulation in the core is exactly the same as it is in XSUBs - see L, L and L for a longer description of the macros used in stack manipulation. =end original コアでの引数スタック操作は、XSUBs とまったく同じです - スタック操作で 使われるマクロのより長い説明については、 L、L、L を参照してください。 =item Mark stack (マークスタック) =begin original I say "your portion of the stack" above because PP code doesn't necessarily get the whole stack to itself: if your function calls another function, you'll only want to expose the arguments aimed for the called function, and not (necessarily) let it get at your own data. The way we do this is to have a "virtual" bottom-of-stack, exposed to each function. The mark stack keeps bookmarks to locations in the argument stack usable by each function. For instance, when dealing with a tied variable, (internally, something with "P" magic) Perl has to call methods for accesses to the tied variables. However, we need to separate the arguments exposed to the method to the argument exposed to the original function - the store or fetch or whatever it may be. Here's roughly how the tied C is implemented; see C in F: =end original 上で「スタックのあなたの部分」と言ったのは、PP コードが必ずしも スタック全体を自分自身に取得する必要はないからです: 関数が別の関数を呼び出す場合は、呼び出された関数を対象とした引数を 公開するだけで、(必ずしも)自分自身のデータを取得させるわけではありません。 これを行う方法は、各関数に公開される「仮想的な」スタックの最下位を 持つことです。 マークスタックは、各関数が使える引数スタック内の場所への ブックマークを保持します。 例えば、tie された変数を扱う場合(内部では "P" マジックのようなもの)、 Perl は tie された変数にアクセスするためにメソッドを呼び出す必要があります。 ただし、メソッドに公開される引数を、元の関数に公開される引数(store や fetch など)に分離する必要があります。 tie された C がどのように実装されるかを大まかに説明します; F の C を参照してください。 1 PUSHMARK(SP); 2 EXTEND(SP,2); 3 PUSHs(SvTIED_obj((SV*)av, mg)); 4 PUSHs(val); 5 PUTBACK; 6 ENTER; 7 call_method("PUSH", G_SCALAR|G_DISCARD); 8 LEAVE; =begin original Let's examine the whole implementation, for practice: =end original 実践のために、実装全体を調べてみましょう: 1 PUSHMARK(SP); =begin original Push the current state of the stack pointer onto the mark stack. This is so that when we've finished adding items to the argument stack, Perl knows how many things we've added recently. =end original スタックポインタの現在の状態をマークスタックにプッシュします。 これは、引数スタックへの項目の追加が完了したときに、Perl が最近追加した 項目の数を知るためです。 2 EXTEND(SP,2); 3 PUSHs(SvTIED_obj((SV*)av, mg)); 4 PUSHs(val); =begin original We're going to add two more items onto the argument stack: when you have a tied array, the C subroutine receives the object and the value to be pushed, and that's exactly what we have here - the tied object, retrieved with C, and the value, the SV C. =end original 引数スタックにさらに二つの項目を追加します: tie された配列がある場合、C サブルーチンはオブジェクトと プッシュされる値を受け取ります; そしてこれがここで得られるものです - C で取得された tie されたオブジェクトと、 その値である SV C です。 5 PUTBACK; =begin original Next we tell Perl to update the global stack pointer from our internal variable: C only gave us a local copy, not a reference to the global. =end original 次に、内部変数からグローバルスタックポインタを更新するように Perl に指示します: C はローカルコピーだけを提供し、グローバルへの参照は提供しません。 6 ENTER; 7 call_method("PUSH", G_SCALAR|G_DISCARD); 8 LEAVE; =begin original C and C localise a block of code - they make sure that all variables are tidied up, everything that has been localised gets its previous value returned, and so on. Think of them as the C<{> and C<}> of a Perl block. =end original C と C はコードブロックをローカル化します - すべての変数が 整理されていること、ローカル化されたすべてのものが以前の値を返すことなどを 確認します。 これらは Perl ブロックの C<{> と C<}> と考えてください。 =begin original To actually do the magic method call, we have to call a subroutine in Perl space: C takes care of that, and it's described in L. We call the C method in scalar context, and we're going to discard its return value. The call_method() function removes the top element of the mark stack, so there is nothing for the caller to clean up. =end original マジックメソッド呼び出しを実際に行うためには、Perl 空間でサブルーチンを 呼び出す必要があります: C がこれを処理します; これについては L で説明しています。 C メソッドをスカラコンテキストで呼び出し、その戻り値を破棄します。 call_method() 関数はマークスタックの最上位要素を削除するため、 呼び出し側がクリーンアップするものはありません。 =item Save stack =begin original C doesn't have a concept of local scope, so perl provides one. We've seen that C and C are used as scoping braces; the save stack implements the C equivalent of, for example: =end original C にはローカルスコープという概念がないので、perl が提供しています。 C と C がスコープを作る中かっことして 使われていることを見てきました; 保存スタックは以下のような C に相当するものを実装しています: { local $foo = 42; ... } =begin original See L for how to use the save stack. =end original 保存スタックの使い方については、 L を参照してください。 =back =head2 Millions of Macros (大量のマクロ) =begin original One thing you'll notice about the Perl source is that it's full of macros. Some have called the pervasive use of macros the hardest thing to understand, others find it adds to clarity. Let's take an example, the code which implements the addition operator: =end original Perl ソースに関して気付くかも知れない一つのことは、Perl ソースには マクロが豊富に含まれているということです。 マクロが広く使われていることを理解するのが最も難しいとする人もいれば、 マクロが明快さを増すと考える人もいます。 例えば、加算演算子を実装するコードを例にとりましょう: 1 PP(pp_add) 2 { 3 dSP; dATARGET; tryAMAGICbin(add,opASSIGN); 4 { 5 dPOPTOPnnrl_ul; 6 SETn( left + right ); 7 RETURN; 8 } 9 } =begin original Every line here (apart from the braces, of course) contains a macro. The first line sets up the function declaration as Perl expects for PP code; line 3 sets up variable declarations for the argument stack and the target, the return value of the operation. Finally, it tries to see if the addition operation is overloaded; if so, the appropriate subroutine is called. =end original ここの各行(もちろん中かっこを除く)にはマクロが含まれています。 最初の行は、Perl が PP コードに期待する関数宣言を設定します。 3 行目は、引数スタックと操作の戻り値であるターゲットの変数宣言を設定します。 最後に、加算操作がオーバーロードされているかどうかを調べます; オーバーロードされている場合は、適切なサブルーチンが呼び出されます。 =begin original Line 5 is another variable declaration - all variable declarations start with C - which pops from the top of the argument stack two NVs (hence C) and puts them into the variables C and C, hence the C. These are the two operands to the addition operator. Next, we call C to set the NV of the return value to the result of adding the two values. This done, we return - the C macro makes sure that our return value is properly handled, and we pass the next operator to run back to the main run loop. =end original 5 行目はもう一つの変数宣言です - すべての変数宣言は C で始まります - これは引数スタックの先頭から二つの NV(つまり C)を取り出し、それらを 変数 C と C(つまり C)に入れます。 これらは加算演算子に対する二つのオペランドです。 次に、C を呼び出して、戻り値の NV を二つの値を加算した結果に 設定します。 これが終われば、返ります - C マクロは返り値が適切に処理されていることを確認し、 メインの実行ループに戻るために次の演算子を渡します。 =begin original Most of these macros are explained in L, and some of the more important ones are explained in L as well. Pay special attention to L for information on the C<[pad]THX_?> macros. =end original これらのマクロのほとんどは L で説明されていますし、 より重要なマクロのいくつかは L でも説明されています。 C<[pad]THX_?> マクロに関する情報については、 L に特に注意してください。 =head2 The .i Targets (.i ターゲット) =begin original You can expand the macros in a F file by saying =end original 以下のようにすることで、F ファイルのマクロを展開できます make foo.i =begin original which will expand the macros using cpp. Don't be scared by the results. =end original これは cpp を使ってマクロを展開します。 結果によって怯えないでください。 =head1 SOURCE CODE STATIC ANALYSIS (ソースコード静的解析) =begin original Various tools exist for analysing C source code B, as opposed to B, that is, without executing the code. It is possible to detect resource leaks, undefined behaviour, type mismatches, portability problems, code paths that would cause illegal memory accesses, and other similar problems by just parsing the C code and looking at the resulting graph, what does it tell about the execution and data flows. As a matter of fact, this is exactly how C compilers know to give warnings about dubious code. =end original C ソースコードを B<静的> に、つまり B<動的> とは対照的に、コードを実行せずに 分析するためのさまざまなツールが存在します。 リソースリーク、未定義動作、型の不一致、移植性の問題、不正なメモリアクセスを 引き起こすコードパス、その他同様の問題は、単に C コードを解析して結果の グラフを見るだけで、実行とデータフローについて何がわかるかを 検出することができます。 実際のところ、 C コンパイラが疑わしいコードについて警告を発する方法は まさにこれです。 =head2 lint, splint =begin original The good old C code quality inspector, C, is available in several platforms, but please be aware that there are several different implementations of it by different vendors, which means that the flags are not identical across different platforms. =end original 古き良き C コード品質インスペクタである Cは、いくつかの プラットフォームで利用できますが、異なるベンダーによるいくつかの 異なる実装があることに注意してください; つまり、フラグは異なるプラットフォーム間で同一ではありません。 =begin original There is a lint variant called C (Secure Programming Lint) available from http://www.splint.org/ that should compile on any Unix-like platform. =end original http://www.splint.org/ から利用可能な C (Secure Programming Lint) と呼ばれる lint の亜種があり、 どんな Unix 風のプラットフォームでもコンパイルできるはずです。 =begin original There are C and targets in Makefile, but you may have to diddle with the flags (see above). =end original Makefile には C ターゲットがありますが、フラグ(上記参照)を いじってみる必要があるかもしれません。 =head2 Coverity =begin original Coverity (http://www.coverity.com/) is a product similar to lint and as a testbed for their product they periodically check several open source projects, and they give out accounts to open source developers to the defect databases. =end original Coverity (http://www.coverity.com/) は lint に似た製品で、彼らの製品の テストベッドとして、彼らは定期的にいくつかのオープンソースプロジェクトを チェックし、オープンソース開発者に欠陥データベースのアカウントを 提供しています。 =head2 cpd (cut-and-paste detector) (cpd (コピペ検出器)) =begin original The cpd tool detects cut-and-paste coding. If one instance of the cut-and-pasted code changes, all the other spots should probably be changed, too. Therefore such code should probably be turned into a subroutine or a macro. =end original cpd ツールはカットアンドペーストのコーディングを検出します。 カットアンドペーストされたコードの一つのインスタンスが変更されると、 他のすべてのスポットも変更される必要があります。 したがって、そのようなコードはサブルーチンまたはマクロに変換される 必要があります。 =begin original cpd (http://pmd.sourceforge.net/cpd.html) is part of the pmd project (http://pmd.sourceforge.net/). pmd was originally written for static analysis of Java code, but later the cpd part of it was extended to parse also C and C++. =end original cpd (http://pmd.sourceforge.net/cpd.html) は pmd プロジェクトの一部です (http://pmd.sourceforge.net/)。 pmd はもともと Java コードの静的解析のために書かれましたが、後に cpd 部分が拡張されて C と C++ も解析できるようになりました。 =begin original Download the pmd-bin-X.Y.zip () from the SourceForge site, extract the pmd-X.Y.jar from it, and then run that on source code thusly: =end original SourceForge のサイトからpmd-bin-X.Y.zip()をダウンロードし、そこから pmd-X.Y.jar を抽出し、次のようにソースコードに対して実行します: java -cp pmd-X.Y.jar net.sourceforge.pmd.cpd.CPD --minimum-tokens 100 --files /some/where/src --language c > cpd.txt =begin original You may run into memory limits, in which case you should use the -Xmx option: =end original メモリ制限に到達する場合があります。 その場合は-Xmxオプションを使ってください: java -Xmx512M ... =head2 gcc warnings (gcc の警告) =begin original Though much can be written about the inconsistency and coverage problems of gcc warnings (like C<-Wall> not meaning "all the warnings", or some common portability problems not being covered by C<-Wall>, or C<-ansi> and C<-pedantic> both being a poorly defined collection of warnings, and so forth), gcc is still a useful tool in keeping our coding nose clean. =end original (C<-Wall> が「全ての警告」を意味しなかったり、C<-Wall> が基本的な移植性問題に 対応していなかったり、C<-ansi> と C<-pedantic> の両方は対応する警告が 貧弱であったり、というような) gcc の警告に関する非一貫性と対応範囲についての 問題点はたくさん書かれてはいますが、gcc は未だにコードをきれいに保つのに 有用なツールです。 =begin original The C<-Wall> is by default on. =end original C<-Wall> はデフォルトでオンです。 =begin original The C<-ansi> (and its sidekick, C<-pedantic>) would be nice to be on always, but unfortunately they are not safe on all platforms, they can for example cause fatal conflicts with the system headers (Solaris being a prime example). If Configure C<-Dgccansipedantic> is used, the C frontend selects C<-ansi -pedantic> for the platforms where they are known to be safe. =end original C<-ansi> (およびその親類である C<-pedantic>) も常にオンにしたいですが、 残念ながら全てのプラットフォームで安全というわけではありません; 例えば システムヘッダと致命的な衝突を引き起こすことがあります (Solaris が 第一の例です)。 Configure で C<-Dgccansipedantic> を使うと、C フロントエンドは 安全と分かっているプラットフォームでだけ C<-ansi -pedantic> を選択します。 =begin original Starting from Perl 5.9.4 the following extra flags are added: =end original Perl 5.9.4 から以下のフラグが追加されました: =over 4 =item * C<-Wendif-labels> =item * C<-Wextra> =item * C<-Wdeclaration-after-statement> =back =begin original The following flags would be nice to have but they would first need their own Augean stablemaster: =end original 以下のフラグがあると便利ですが、最初に整理が必要です: =over 4 =item * C<-Wpointer-arith> =item * C<-Wshadow> =item * C<-Wstrict-prototypes> =back =begin original The C<-Wtraditional> is another example of the annoying tendency of gcc to bundle a lot of warnings under one switch (it would be impossible to deploy in practice because it would complain a lot) but it does contain some warnings that would be beneficial to have available on their own, such as the warning about string constants inside macros containing the macro arguments: this behaved differently pre-ANSI than it does in ANSI, and some C compilers are still in transition, AIX being an example. =end original C<-Wtraditional> は、gcc が一つのスイッチに多数の警告をバンドルするという 厄介な傾向のもう一つの例です (多くの警告が 出るので、実際に展開することは不可能です) しかし、C<-Wtraditional> には、 マクロ引数を含むマクロ内の文字列定数に関する警告など、単独で 利用できるようにしておくと有益な警告がいくつか含まれています: これは ANSI 以前と ANSI では動作が異なり、いくつかのCコンパイラは まだ移行中で、AIX がその一例です。 =head2 Warnings of other C compilers (その他の C コンパイラの警告) =begin original Other C compilers (yes, there B other C compilers than gcc) often have their "strict ANSI" or "strict ANSI with some portability extensions" modes on, like for example the Sun Workshop has its C<-Xa> mode on (though implicitly), or the DEC (these days, HP...) has its C<-std1> mode on. =end original 他の C コンパイラ(もちろん、gcc 以外の C コンパイラも B<あります>)はしばしば 「厳密な ANSI」 や 「厳密な ANSI といくつかの移植性の拡張」モードを オンにしています; 例えば、Sun Workshop では C<-Xa> モードが(暗黙的ですが)オンになっていたり、 DEC (最近では HP…)では C<-std1> モードがオンになっていたりします。 =head2 DEBUGGING (デバッグ) =begin original You can compile a special debugging version of Perl, which allows you to use the C<-D> option of Perl to tell more about what Perl is doing. But sometimes there is no alternative than to dive in with a debugger, either to see the stack trace of a core dump (very useful in a bug report), or trying to figure out what went wrong before the core dump happened, or how did we end up having wrong or unexpected results. =end original Perlの C<-D> オプションを使って、Perl が何をしているのかを詳しく 知ることができるように、Perl の特別なデバッグバージョンを コンパイルすることができます。 しかし、場合によっては、デバッガを使って、コアダンプのスタックトレースを 調べたり(バグレポートで非常に役立ちます)、コアダンプが発生する前に何が 間違っていたのかを調べたり、どのようにして間違った結果や予期しない結果に なったのかを調べたりする以外に方法がないこともあります。 =head2 Poking at Perl (Perl をつつく) =begin original To really poke around with Perl, you'll probably want to build Perl for debugging, like this: =end original 実際に Perl をつつくためには、おそらく以下のようにデバッグ用の Perl を ビルドしたいでしょう: ./Configure -d -D optimize=-g make =begin original C<-g> is a flag to the C compiler to have it produce debugging information which will allow us to step through a running program, and to see in which C function we are at (without the debugging information we might see only the numerical addresses of the functions, which is not very helpful). =end original C<-g> は、C コンパイラに対して、実行中のプログラムをステップ実行するため、 そしてどの C 関数にいるのかを調べるためのデバッグ情報を生成させるための フラグです(デバッグ情報がなければ、関数の数値アドレスだけが表示されますが、 あまり役に立ちません)。 =begin original F will also turn on the C compilation symbol which enables all the internal debugging code in Perl. There are a whole bunch of things you can debug with this: L lists them all, and the best way to find out about them is to play about with them. The most useful options are probably =end original F は C コンパイルシンボルも有効にします; これは Perl の全ての内部デバッグコードを有効にします。 これでデバッグできるものはたくさんあります: Lはそれらをすべてリストしています; それらについて知るための最良の方法は、それらをいじってみることです。 最も有用なオプションはおそらく次のようになります: l Context (loop) stack processing t Trace execution o Method and overloading resolution c String/numeric conversions =begin original Some of the functionality of the debugging code can be achieved using XS modules. =end original コードのデバッグの機能の一部は XS モジュールを使って実現できます。 -Dr => use re 'debug' -Dx => use O 'Debug' =head2 Using a source-level debugger (ソースレベルデバッガを使う) =begin original If the debugging output of C<-D> doesn't help you, it's time to step through perl's execution with a source-level debugger. =end original C<-D> のデバッグ出力が役に立たない場合は、ソースレベルのデバッガを使って perl の実行を順に追ってみましょう。 =over 3 =item * =begin original We'll use C for our examples here; the principles will apply to any debugger (many vendors call their debugger C), but check the manual of the one you're using. =end original ここでは例として C を使います; この原則はどのデバッガにも適用されます(多くのベンダーではデバッガを C と呼んでいます)が、使っているデバッガのマニュアルを 確認してください。 =back =begin original To fire up the debugger, type =end original デバッガを起動するには、以下のようにタイプします: gdb ./perl =begin original Or if you have a core dump: =end original あるいはコアダンプがあるなら: gdb ./perl core =begin original You'll want to do that in your Perl source tree so the debugger can read the source code. You should see the copyright message, followed by the prompt. =end original Perl ソースツリーで行い、デバッガがソースコードを読み取ることが できるようにします。 copyrightメッセージに続いてプロンプトが表示されます。 (gdb) =begin original C will get you into the documentation, but here are the most useful commands: =end original C で文書を参照できますが、最も便利なコマンドは以下のとおりです: =over 3 =item run [args] =begin original Run the program with the given arguments. =end original 引数を指定してプログラムを実行します。 =item break function_name =item break source.c:xxx =begin original Tells the debugger that we'll want to pause execution when we reach either the named function (but see L!) or the given line in the named source file. =end original 指定された関数 (ただし L を参照!)または 指定されたソースファイル内の指定された行に到達したときに、実行を 一時停止するようデバッガに指示します。 =item step =begin original Steps through the program a line at a time. =end original 一度に 1 行、プログラムをステップ実行します。 =item next =begin original Steps through the program a line at a time, without descending into functions. =end original 一度に 1 行、関数を下っていかずにプログラムをステップ実行します。 =item continue =begin original Run until the next breakpoint. =end original 次のブレークポイントまで実行します。 =item finish =begin original Run until the end of the current function, then stop again. =end original 現在の関数の末尾まで実行して、もう一度停止します。 =item 'enter' =begin original Just pressing Enter will do the most recent operation again - it's a blessing when stepping through miles of source code. =end original 単に Enter キーを押すと、直前の操作をもう一度実行します - これは 大量のソースコードをステップ実行するときに助けになります。 =item print =begin original Execute the given C code and print its results. B: Perl makes heavy use of macros, and F does not necessarily support macros (see later L). You'll have to substitute them yourself, or to invoke cpp on the source code files (see L) So, for instance, you can't say =end original 指定された C コードを実行し、その結果を出力します。 B<警告>: Perl はマクロを多用していますが、F は必ずしもマクロを サポートしていません(後述の L を参照してください)。 それらを自分で置き換えるか、ソースコードファイルで cpp を起動する 必要があります(L を参照してください)。 ですから例えばこのようにはできず: print SvPV_nolen(sv) =begin original but you have to say =end original 以下のように書く必要があります print Perl_sv_2pv_nolen(sv) =back =begin original You may find it helpful to have a "macro dictionary", which you can produce by saying C. Even then, F won't recursively apply those macros for you. =end original C として生成できる「マクロ辞書」があると 便利かもしれません。 それでも、F はこれらのマクロを再帰的に適用しません。 =head2 gdb macro support (gdb マクロ対応) =begin original Recent versions of F have fairly good macro support, but in order to use it you'll need to compile perl with macro definitions included in the debugging information. Using F version 3.1, this means configuring with C<-Doptimize=-g3>. Other compilers might use a different switch (if they support debugging macros at all). =end original F の最近のバージョンはかなり良いマクロサポートを持っていますが、 それを使うためにはデバッグ情報にマクロ定義が含まれている perl を コンパイルする必要があります。 F バージョン 3.1 を使うと、C<-Doptimize=-g3> で設定することになります。 他のコンパイラは(もしデバッグマクロをサポートしていれば)別のスイッチを 使うかもしれません。 =head2 Dumping Perl Data Structures (Perl データ構造体をダンプする) =begin original One way to get around this macro hell is to use the dumping functions in F; these work a little like an internal L, but they also cover OPs and other structures that you can't get at from Perl. Let's take an example. We'll use the C<$a = $b + $c> we used before, but give it a bit of context: C<$b = "6XXXX"; $c = 2.3;>. Where's a good place to stop and poke around? =end original このマクロ地獄を回避する一つの方法は、F のダンプ関数を 使うことです; これらの関数は、内部の L と少し似た動作ですが、 Perl からは得られない OP やその他の構造体もカバーしています。 例を挙げてみましょう。 前に使った C<$a = $b + $c> を使いますが、C<$b = "6XXXX"; $c = 2.3;> という コンテキストを少し説明します。 立ち止まって歩き回るのに良い場所はどこでしょう? =begin original What about C, the function we examined earlier to implement the C<+> operator: =end original 先ほど C<+> 演算子を実装するために検討した関数 C については どうでしょう: (gdb) break Perl_pp_add Breakpoint 1 at 0x46249f: file pp_hot.c, line 309. =begin original Notice we use C and not C - see L. With the breakpoint in place, we can run our program: =end original C ではなく C を使っていることに注意してください - Lを参照してください。 ブレークポイントを設定すると、プログラムを実行できます: (gdb) run -e '$b = "6XXXX"; $c = 2.3; $a = $b + $c' =begin original Lots of junk will go past as gdb reads in the relevant source files and libraries, and then: =end original gdb が関連するソースファイルやライブラリを読み込むので 多くのガラクタが通り過ぎ、それから: Breakpoint 1, Perl_pp_add () at pp_hot.c:309 309 dSP; dATARGET; tryAMAGICbin(add,opASSIGN); (gdb) step 311 dPOPTOPnnrl_ul; (gdb) =begin original We looked at this bit of code before, and we said that C arranges for two Cs to be placed into C and C - let's slightly expand it: =end original 前にこのコードを見ましたが、C は二つの C を C と C に配置するようにアレンジしていると言いました - 少し拡張してみましょう: #define dPOPTOPnnrl_ul NV right = POPn; \ SV *leftsv = TOPs; \ NV left = USE_LEFT(leftsv) ? SvNV(leftsv) : 0.0 =begin original C takes the SV from the top of the stack and obtains its NV either directly (if C is set) or by calling the C function. C takes the next SV from the top of the stack - yes, C uses C - but doesn't remove it. We then use C to get the NV from C in the same way as before - yes, C uses C. =end original C はスタックの先頭から SV を取得し、直接(C が設定されている 場合)または C 関数を呼び出すことによって NV を取得します。 C はスタックの先頭から次の SV を取得します - はい、C は C を使います - ただし、SV は削除されません。 次に C を使って、以前と同じ方法で C から NV を取得します - はい、C は C を使います。 =begin original Since we don't have an NV for C<$b>, we'll have to use C to convert it. If we step again, we'll find ourselves there: =end original C<$b> には NV がないので、C を使って変換する必要があります。 もう一度ステップ実行すると、そこにいることがわかるでしょう: Perl_sv_2nv (sv=0xa0675d0) at sv.c:1669 1669 if (!sv) (gdb) =begin original We can now use C to investigate the SV: =end original 次に、C を使って SV を調査します: SV = PV(0xa057cc0) at 0xa0675d0 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0xa06a510 "6XXXX"\0 CUR = 5 LEN = 6 $1 = void =begin original We know we're going to get C<6> from this, so let's finish the subroutine: =end original ここから C<6> が得られることはわかっているので、サブルーチンを 終了しましょう: (gdb) finish Run till exit from #0 Perl_sv_2nv (sv=0xa0675d0) at sv.c:1671 0x462669 in Perl_pp_add () at pp_hot.c:311 311 dPOPTOPnnrl_ul; =begin original We can also dump out this op: the current op is always stored in C, and we can dump it with C. This'll give us similar output to L. =end original この op をダンプすることもできます: 現在の op は常に C に保存されており、C で ダンプすることができます。 これにより、L と同様の出力が得られます。 { 13 TYPE = add ===> 14 TARG = 1 FLAGS = (SCALAR,KIDS) { TYPE = null ===> (12) (was rv2sv) FLAGS = (SCALAR,KIDS) { 11 TYPE = gvsv ===> 12 FLAGS = (SCALAR) GV = main::b } } # finish this later # =head2 Patching (パッチを当てる) =begin original All right, we've now had a look at how to navigate the Perl sources and some things you'll need to know when fiddling with them. Let's now get on and create a simple patch. Here's something Larry suggested: if a C is the first active format during a C, (for example, C) then the resulting string should be treated as UTF-8 encoded. =end original ここまでで、Perl ソースをナビゲートする方法と、ソースを操作するときに 知っておく必要があることについて説明しました。 では、簡単なパッチを作成してみましょう。 Larry が提案したことは、C が C 中で最初に アクティブなフォーマットである場合(たとえば、C)、 結果の文字列は UTF-8 エンコードとして扱われるべきであるということです。 =begin original If you are working with a git clone of the Perl repository, you will want to create a branch for your changes. This will make creating a proper patch much simpler. See the L for details on how to do this. =end original Perl リポジトリの git クローン上で作業しているなら、 あなたの変更のためのブランチを作成した方が良いでしょう。 これにより適切なパッチの作成がを大幅に簡単になります。 この方法に関する詳細については L を参照してください。 =begin original How do we prepare to fix this up? First we locate the code in question - the C happens at runtime, so it's going to be in one of the F files. Sure enough, C is in F. Since we're going to be altering this file, let's copy it to F. =end original この問題を解決するための準備はどうすればいいでしょう? まず問題のコードを見つけます - C は実行時に発生するので、 F ファイルの一つにあるはずです。 C は F にあります。 このファイルを変更するので、F にコピーします。 =begin original [Well, it was in F when this tutorial was written. It has now been split off with C to its own file, F] =end original [そうですね、このチュートリアルが書かれたときは F に書かれていました。 現在は C とともに独自のファイル F に分割されています] =begin original Now let's look over C: we take a pattern into C, and then loop over the pattern, taking each format character in turn into C. Then for each possible format character, we swallow up the other arguments in the pattern (a field width, an asterisk, and so on) and convert the next chunk input into the specified format, adding it onto the output SV C. =end original Cを見てみましょう: パターンを C に取り込み、そのパターンをループして、各フォーマット文字を 順番に C に取り込みます。 次に、可能なフォーマット文字ごとに、パターン内の他の引数 (フィールド幅やアスタリスクなど)を取り込み、 次のチャンク入力を指定されたフォーマットに変換し、 出力 SV C に追加します。 =begin original How do we know if the C is the first format in the C? Well, if we have a pointer to the start of C then, if we see a C we can test whether we're still at the start of the string. So, here's where C is set up: =end original C が C の最初のフォーマットであるかどうかはどうすれば わかるでしょう? さて、C の先頭へのポインタがあれば、C が見つかったら、 まだ文字列の先頭にいるかどうかをテストできます。 ここで C が設定されています: STRLEN fromlen; register char *pat = SvPVx(*++MARK, fromlen); register char *patend = pat + fromlen; register I32 len; I32 datumtype; SV *fromstr; =begin original We'll have another string pointer in there: =end original ここには別の文字列ポインタがあります: STRLEN fromlen; register char *pat = SvPVx(*++MARK, fromlen); register char *patend = pat + fromlen; + char *patcopy; register I32 len; I32 datumtype; SV *fromstr; =begin original And just before we start the loop, we'll set C to be the start of C: =end original ループを開始する直前に、C を C の開始点に設定します。 items = SP - MARK; MARK++; sv_setpvn(cat, "", 0); + patcopy = pat; while (pat < patend) { =begin original Now if we see a C which was at the start of the string, we turn on the C flag for the output SV, C: =end original 文字列の先頭に C がある場合、出力 SV である Cに対して C フラグをオンにします。 + if (datumtype == 'U' && pat==patcopy+1) + SvUTF8_on(cat); if (datumtype == '#') { while (pat < patend && *pat != '\n') pat++; =begin original Remember that it has to be C because the first character of the string is the C which has been swallowed into C =end original 文字列の最初の文字は C に飲み込まれたCなので、 これは C でなければならないことを覚えておいてください! =begin original Oops, we forgot one thing: what if there are spaces at the start of the pattern? C will have C as the first active character, even though it's not the first thing in the pattern. In this case, we have to advance C along with C when we see spaces: =end original おっと、ひとつ忘れていました: パターンの先頭にスペースがあったら? C は、パターンの先頭ではないにもかかわらず、 最初のアクティブな文字として C を持ちます。 この場合、スペースがあるときは、C とともに C を 進める必要があります: if (isSPACE(datumtype)) continue; =begin original needs to become =end original これは次のようにする必要があります: if (isSPACE(datumtype)) { patcopy++; continue; } =begin original OK. That's the C part done. Now we must do two additional things before this patch is ready to go: we've changed the behaviour of Perl, and so we must document that change. We must also provide some more regression tests to make sure our patch works and doesn't create a bug somewhere else along the line. =end original OK。 これで C の部分は完了です。 次に、このパッチを準備する前に、次の二つのことを行う必要があります: Perlの動作を変更したので、その変更を文書化する必要があります。 また、パッチが動作し、他の場所でバグが発生しないことを確認するために、 さらに回帰テストを提供する必要があります。 =begin original The regression tests for each operator live in F, and so we make a copy of F to F. Now we can add our tests to the end. First, we'll test that the C does indeed create Unicode strings. =end original 各演算子の退行テストは F に存在するため、 F から F へのコピーを作成します。 これで、テストを最後に追加できます。 まず、C が実際に Unicode 文字列を作成することをテストします。 =begin original t/op/pack.t has a sensible ok() function, but if it didn't we could use the one from t/test.pl. =end original t/op/pack.t には適切な ok() 関数がありますが、そうでなければ t/test.pl の関数を使うことができます。 require './test.pl'; plan( tests => 159 ); =begin original so instead of this: =end original それで次のようにする代わりに: print 'not ' unless "1.20.300.4000" eq sprintf "%vd", pack("U*",1,20,300,4000); print "ok $test\n"; $test++; =begin original we can write the more sensible (see L for a full explanation of is() and other testing functions). =end original より実用的な関数を書くことができます (is() やその他のテスト関数の詳細については L を参照してください)。 is( "1.20.300.4000", sprintf "%vd", pack("U*",1,20,300,4000), "U* produces Unicode" ); =begin original Now we'll test that we got that space-at-the-beginning business right: =end original では、私たちが最初の場所でビジネスの権利を得たことを テストしてみましょう: is( "1.20.300.4000", sprintf "%vd", pack(" U*",1,20,300,4000), " with spaces at the beginning" ); =begin original And finally we'll test that we don't make Unicode strings if C is B the first active format: =end original 最後に、C が B である場合、Unicode 文字列を作成しないことを テストします: isnt( v1.20.300.4000, sprintf "%vd", pack("C0U*",1,20,300,4000), "U* not first isn't Unicode" ); =begin original Mustn't forget to change the number of tests which appears at the top, or else the automated tester will get confused. This will either look like this: =end original 一番上にあるテストの数を変更することを忘れないでください; さもないと、自動化されたテスターが混乱します。 これは以下のようになります: print "1..156\n"; =begin original or this: =end original または次のようになります: plan( tests => 156 ); =begin original We now compile up Perl, and run it through the test suite. Our new tests pass, hooray! =end original 今度は Perl をコンパイルして、テストスイートで実行します。 新しいテストに合格しました、万歳! =begin original Finally, the documentation. The job is never done until the paperwork is over, so let's describe the change we've just made. The relevant place is F; again, we make a copy, and then we'll insert this text in the description of C: =end original 最後に、文書です。 事務処理が終わるまで仕事は終わらないので、 今行った変更について説明しましょう。 関連する場所は F です; ここでもコピーを作成し、C の説明に次のテキストを挿入します: =item * If the pattern begins with a C, the resulting string will be treated as UTF-8-encoded Unicode. You can force UTF-8 encoding on in a string with an initial C, and the bytes that follow will be interpreted as Unicode characters. If you don't want this to happen, you can begin your pattern with C (or anything else) to force Perl not to UTF-8 encode your string, and then follow this with a C somewhere in your pattern. =head2 Patching a core module (コアモジュールにパッチを当てる) =begin original This works just like patching anything else, with an extra consideration. Many core modules also live on CPAN. If this is so, patch the CPAN version instead of the core and send the patch off to the module maintainer (with a copy to p5p). This will help the module maintainer keep the CPAN version in sync with the core version without constantly scanning p5p. =end original これは他のパッチと同じように動作しますが、特別な注意が必要です。 多くのコアモジュールは CPAN 上にもあります。 その場合は、コアではなく CPAN バージョンにパッチを適用し、 モジュールメンテナにパッチを送ります(p5p へのコピーと共に)。 これは、モジュールメンテナが p5p を絶えずスキャンすることなく、 CPAN バージョンをコアバージョンと同期させるのに役立ちます。 =begin original The list of maintainers of core modules is usefully documented in F. =end original コアモジュールのメンテナのリストは、F に 記載されています。 =head2 Adding a new function to the core (コアに新しい関数を追加する) =begin original If, as part of a patch to fix a bug, or just because you have an especially good idea, you decide to add a new function to the core, discuss your ideas on p5p well before you start work. It may be that someone else has already attempted to do what you are considering and can give lots of good advice or even provide you with bits of code that they already started (but never finished). =end original バグを修正するためのパッチの一部として、または単に特別に優れたアイデアが あるという理由で、コアに新しい関数を追加することに決めた場合は、 作業を始める前に p5p でアイデアについて十分に議論してください。 あなたが考えていることを他の誰かがすでに実行しようとしており、多くの 優れたアドバイスを与えてくれたり、彼らがすでに開始している (まだ完了していない)コードの一部を提供したりしている可能性すらあります。 =begin original You have to follow all of the advice given above for patching. It is extremely important to test any addition thoroughly and add new tests to explore all boundary conditions that your new function is expected to handle. If your new function is used only by one module (e.g. toke), then it should probably be named S_your_function (for static); on the other hand, if you expect it to accessible from other functions in Perl, you should name it Perl_your_function. See L for more details. =end original パッチ適用については、前述のすべてのアドバイスに従う必要があります。 追加を徹底的にテストし、新しいテストを追加して、新しい関数が処理すると 予想されるすべての境界条件を調べることが非常に重要です。 新しい関数が一つのモジュール(toke など)のみで使われる場合は、 (static から) S_your_function という名前にする必要があります; 一方、Perl の他の関数からアクセスできると予想される場合は、 Perl_your_function という名前にする必要があります。 更なる詳細については、L を参照してください。 =begin original The location of any new code is also an important consideration. Don't just create a new top level .c file and put your code there; you would have to make changes to Configure (so the Makefile is created properly), as well as possibly lots of include files. This is strictly pumpking business. =end original 新しいコードの場所も重要な考慮事項です。 単に新しい最上位レベルの .c ファイルを作成してそこにコードを 置かないでください; Configure を変更し(Makefile が正しく作成されるように)、 多くのインクルードファイルも変更する必要があります。 これはまさにパンプキンの仕事です。 =begin original It is better to add your function to one of the existing top level source code files, but your choice is complicated by the nature of the Perl distribution. Only the files that are marked as compiled static are located in the perl executable. Everything else is located in the shared library (or DLL if you are running under WIN32). So, for example, if a function was only used by functions located in toke.c, then your code can go in toke.c. If, however, you want to call the function from universal.c, then you should put your code in another location, for example util.c. =end original 既存のトップレベルソースコードファイルの一つに関数を追加することを お薦めしますが、Perl 配布の性質上、選択が複雑になります。 コンパイル済み静的としてマークされたファイルのみが perl 実行可能ファイルに 配置されます。 その他はすべて共有ライブラリ(または WIN32 で実行している場合は DLL)に 配置されます。 たとえば、ある関数が toke.c にある関数によってのみ使われていた場合、 コードは toke.c に配置できます。 ただし、universal.c から関数を呼び出す場合は、util.c などの別の場所に コードを配置する必要があります。 =begin original In addition to writing your c-code, you will need to create an appropriate entry in embed.pl describing your function, then run 'make regen_headers' to create the entries in the numerous header files that perl needs to compile correctly. See L for information on the various options that you can set in embed.pl. You will forget to do this a few (or many) times and you will get warnings during the compilation phase. Make sure that you mention this when you post your patch to P5P; the pumpking needs to know this. =end original c コードを書くことに加えて、embed.pl に関数を記述する適切なエントリを 作成する必要があります。 そして 'make regen_headers' を実行して、perl が正しくコンパイルするために 必要な多数のヘッダファイルにエントリを作成します。 embed.pl に設定できるさまざまなオプションについては、 L を参照してください。 これを何回か(あるいは何回も)行うことを忘れ、コンパイル時に 警告が表示されることになるでしょう。 P5Pに パッチを投稿する際には、このことを必ず伝えてください; パンプキンはこのことを知る必要があります。 =begin original When you write your new code, please be conscious of existing code conventions used in the perl source files. See L for details. Although most of the guidelines discussed seem to focus on Perl code, rather than c, they all apply (except when they don't ;). Also see I for lots of details about both formatting and submitting patches of your changes. =end original 新しいコードを作成する際には、perl ソースファイルで使われている既存の コード規則に従ってください。 詳細は L を参照してください。 議論されているガイドラインのほとんどは、c ではなく Perl コードに焦点を 当てているようですが、それらはすべて適用されます(適用されない場合を 除きます ;)。 また、変更のパッチの書式設定と送信の詳細については I も参照してください。 =begin original Lastly, TEST TEST TEST TEST TEST any code before posting to p5p. Test on as many platforms as you can find. Test as many perl Configure options as you can (e.g. MULTIPLICITY). If you have profiling or memory tools, see L below for how to use them to further test your code. Remember that most of the people on P5P are doing this on their own time and don't have the time to debug your code. =end original 最後に、p5p に投稿する前に、全てのコードを テストテストテストテストテストします。 可能な限り多くのプラットフォームでテストします。 可能な限り多くの perl Configure オプションでテストします (例: MULTIPLICITY)。 プロファイルツールやメモリツールをお持ちの場合は、以下の L を参照して、これらのツールを使って コードをさらにテストする方法を確認してください。 p5p のほとんどの人は、自分の時間でこれを行っており、あなたのコードを デバッグする時間がないことを覚えておいてください。 =head2 Writing a test (テストを書く) =begin original Every module and built-in function has an associated test file (or should...). If you add or change functionality, you have to write a test. If you fix a bug, you have to write a test so that bug never comes back. If you alter the docs, it would be nice to test what the new documentation says. =end original すべてのモジュールおよび組み込み関数には関連付けられたテストファイルが あります。 (または そうあるべきです…)。 機能を追加または変更する場合は、テストを記述する必要があります。 バグを修正する場合は、バグが再発しないようにテストを記述する必要があります。 文書を変更する場合は、新しい文書に記載されている内容を テストするとよいでしょう。 =begin original In short, if you submit a patch you probably also have to patch the tests. =end original つまり、パッチを送信する場合は、おそらくテストにもパッチを 当てる必要があります。 =begin original For modules, the test file is right next to the module itself. F tests F. This is a recent innovation, so there are some snags (and it would be wonderful for you to brush them out), but it basically works that way. Everything else lives in F. =end original モジュールの場合、テストファイルはモジュール自体のすぐ隣にあります。 F は F をテストします。 これは最近のイノベーションなので、いくつかの障害があります (そしてそれらを取り除くことは素晴らしいことです)が、 基本的にはそのように機能します。 他のすべては F に存在します。 =begin original If you add a new test directory under F, it is imperative that you add that directory to F and F. =end original F の下に新しいテストディレクトリを追加する場合は、そのディレクトリを F と F に追加する必要があります。 =over 3 =item F =begin original Testing of the absolute basic functionality of Perl. Things like C, basic file reads and writes, simple regexes, etc. These are run first in the test suite and if any of them fail, something is I broken. =end original Perl の絶対的な基本機能のテスト。 C、基本的なファイルの読み書き、単純な正規表現など。 これらはテストスイートで最初に実行され、それらのいずれかが失敗した場合、 何かが I<本当に> 壊れていることになります。 =item F =begin original These test the basic control structures, C, C, subroutines, etc. =end original これらは、基本制御構造、C、C、サブルーチンなどを テストします。 =item F =begin original Tests basic issues of how Perl parses and compiles itself. =end original Perl の構文解析およびコンパイル方法に関する基本的な問題をテストします。 =item F =begin original Tests for built-in IO functions, including command line arguments. =end original コマンドライン引数を含む組み込み IO 関数をテストします。 =item F =begin original The old home for the module tests, you shouldn't put anything new in here. There are still some bits and pieces hanging around in here that need to be moved. Perhaps you could move them? Thanks! =end original モジュールテストの古いホームです; ここに新しいものを置くべきではありません。 ここにはまだ動かす必要のあるいくつかの断片が残っています。 それらを動かすことはできますか? ありがとう! =item F =begin original Tests for perl's method resolution order implementations (see L). =end original perl のメソッド解決順序実装(L を参照)をテストします。 =item F =begin original Tests for perl's built in functions that don't fit into any of the other directories. =end original perl に組み込まれている関数のうち、他のどのディレクトリにも適合しない 関数をテストします。 =item F =begin original Tests for regex related functions or behaviour. (These used to live in t/op). =end original 正規表現関係の関数や振る舞いに関するテストをします。 (これらは以前は t/op にありました)。 =item F =begin original Testing features of how perl actually runs, including exit codes and handling of PERL* environment variables. =end original 終了コードや PERL* 環境変数の処理など、perl が 実際にどのように実行されるかをテストします。 =item F =begin original Tests for the core support of Unicode. =end original Unicode のコア対応をテストします。 =item F =begin original Windows-specific tests. =end original Windows 固有のテスト。 =item F =begin original A test suite for the s2p converter. =end original s2p コンバータ用のテストスイート。 =back =begin original The core uses the same testing style as the rest of Perl, a simple "ok/not ok" run through Test::Harness, but there are a few special considerations. =end original コアは Perl の他の部分と同じテストスタイルを使っており、 Test::Harness を通して単純な「ok/not ok」を実行しますが、 いくつか特別な考慮事項があります。 =begin original There are three ways to write a test in the core. Test::More, t/test.pl and ad hoc C. The decision of which to use depends on what part of the test suite you're working on. This is a measure to prevent a high-level failure (such as Config.pm breaking) from causing basic functionality tests to fail. =end original コアにテストを記述する方法は三つあります。 Test::More, t/test.pl, アドホックな C です。 どれを使うかは、テストスイートのどの部分で 作業しているかによって決まります。 これは、高レベルの障害(Config.pm の破損など)によって基本的な機能テストが 失敗しないようにするための手段です。 =over 4 =item t/base t/comp =begin original Since we don't know if require works, or even subroutines, use ad hoc tests for these two. Step carefully to avoid using the feature being tested. =end original require が動作するのか、あるいはサブルーチンでさえも分からないので、 この二つに対してはアドホックテストを使ってください。 テスト中の機能を使わないように注意してください。 =item t/cmd t/run t/io t/op =begin original Now that basic require() and subroutines are tested, you can use the t/test.pl library which emulates the important features of Test::More while using a minimum of core features. =end original これで基本的な require() とサブルーチンがテストされたので、最小限のコア機能を 使いながら Test::More の重要な機能をエミュレートする t/test.pl ライブラリを 使うことができます。 =begin original You can also conditionally use certain libraries like Config, but be sure to skip the test gracefully if it's not there. =end original Config のような特定のライブラリを条件付きで使うこともできますが、 テストがない場合にはテストを省略するようにしてください。 =item t/lib ext lib =begin original Now that the core of Perl is tested, Test::More can be used. You can also use the full suite of core modules in the tests. =end original Perl のコアがテストされたので、Test::More を使うことができます。 また、コアモジュールの完全なスイートをテストで使うこともできます。 =back =begin original When you say "make test" Perl uses the F program to run the test suite (except under Win32 where it uses F instead.) All tests are run from the F directory, B the directory which contains the test. This causes some problems with the tests in F, so here's some opportunity for some patching. =end original "make test" とすれば、Perl は F プログラムを使って テストスイートを実行します(Win32 では、代わりに F を使います)。 すべてのテストは F ディレクトリから実行され、テストを含む ディレクトリでは B<ありません>。 このため、F 内のテストで問題が発生するので、パッチを適用する 機会があります。 =begin original You must be triply conscious of cross-platform concerns. This usually boils down to using File::Spec and avoiding things like C and C unless absolutely necessary. =end original クロスプラットフォームに関する懸念を 3 倍意識する必要があります。 これは通常、File::Spec を使い、絶対に必要でない限り C や C のようなものを避けることに要約されます。 =head2 Special Make Test Targets (特殊 make test ターゲット) =begin original There are various special make targets that can be used to test Perl slightly differently than the standard "test" target. Not all them are expected to give a 100% success rate. Many of them have several aliases, and many of them are not available on certain operating systems. =end original 標準の "test" ターゲットとは若干異なる方法で Perl をテストするために 使える特殊な make ターゲットがいくつかあります。 すべての make ターゲットが 100% の成功率を示すとは限りません。 これらの多くには複数の別名があり、その多くは特定の オペレーティングシステムでは使えません。 =over 4 =item coretest =begin original Run F on all core tests (F and F pragma tests). =end original 全てのコアテスト (F と F プラグマテスト) で F を 実行します。 =begin original (Not available on Win32) =end original (Win32 では利用できません) =item test.deparse =begin original Run all the tests through B::Deparse. Not all tests will succeed. =end original 全てのテストを B::Deparse を通して実行します。 全てのテストが成功するわけではありません。 =begin original (Not available on Win32) =end original (Win32 では利用できません) =item test.taintwarn =begin original Run all tests with the B<-t> command-line switch. Not all tests are expected to succeed (until they're specifically fixed, of course). =end original 全てのテストを B<-t> コマンドラインスイッチ付きで実行します。 全てのテストが成功するとは想定されません(もちろん具体的に修正するまでです)。 =begin original (Not available on Win32) =end original (Win32 では利用できません) =item minitest =begin original Run F on F, F, F, F, F, F, F and F tests. =end original F, F, F, F, F, F, F, F テストで F を実行します。 =item test.valgrind check.valgrind utest.valgrind ucheck.valgrind =begin original (Only in Linux) Run all the tests using the memory leak + naughty memory access tool "valgrind". The log files will be named F. =end original (Linux のみ) 全てのテストをメモリリーク+メモリアクセスツール "valgrind" を使って実行します。 ログファイルの名前は F です。 =item test.third check.third utest.third ucheck.third =begin original (Only in Tru64) Run all the tests using the memory leak + naughty memory access tool "Third Degree". The log files will be named F. =end original (Tru64 のみ) 全てのテストをメモリリーク+メモリアクセスツール "Third Degree" を使って実行します。 ログファイルの名前は F です。 =item test.torture torturetest =begin original Run all the usual tests and some extra tests. As of Perl 5.8.0 the only extra tests are Abigail's JAPHs, F. =end original 全ての通常のテストといくつかの追加のテストを実行します。 Perl 5.8.0 から、追加のテストは Abigail の JAPHs, F だけです。 =begin original You can also run the torture test with F by giving C<-torture> argument to F. =end original F に C<-torture> 引数を与えることでも F で耐久テストを 実行できます。 =item utest ucheck test.utf8 check.utf8 =begin original Run all the tests with -Mutf8. Not all tests will succeed. =end original 全てのテストを -Mutf8 で実行します。 全てのテストが成功するわけではありません。 =begin original (Not available on Win32) =end original (Win32 では利用できません) =item minitest.utf16 test.utf16 =begin original Runs the tests with UTF-16 encoded scripts, encoded with different versions of this encoding. =end original UTF-16 の様々なバージョンでエンコードされたスクリプトでテストを 実行します。 =begin original C runs the test suite with a combination of C<-utf8> and C<-utf16> arguments to F. =end original C は F へ C<-utf8> と C<-utf16> 引数を組み合わせて テストスイートを実行します。 =begin original (Not available on Win32) =end original (Win32 では利用できません) =item test_harness =begin original Run the test suite with the F controlling program, instead of F. F is more sophisticated, and uses the L module, thus using this test target supposes that perl mostly works. The main advantage for our purposes is that it prints a detailed summary of failed tests at the end. Also, unlike F, it doesn't redirect stderr to stdout. =end original F ではなく、F 制御プログラムでテストスイートを実行します。 F はより洗練されており、L モジュールを使います; したがって、このテストターゲットを使うと、perl はほとんど動作すると 想定されます。 私たちの目的にとっての主な利点は、失敗したテストの詳細な要約が最後に 出力されることです。 また、F とは異なり、stderr を stdout にリダイレクトしません。 =begin original Note that under Win32 F is always used instead of F, so there is no special "test_harness" target. =end original Win32 では、F の代わりに常に F が使われるので、特別な "test_harness" ターゲットはありません。 =begin original Under Win32's "test" target you may use the TEST_SWITCHES and TEST_FILES environment variables to control the behaviour of F. This means you can say =end original Win32の "test" ターゲットでは、環境変数 TEST_SWITCHES とTEST_FILES を 使って F の動作を制御することができます。 これは次のようにできるということです: nmake test TEST_FILES="op/*.t" nmake test TEST_SWITCHES="-torture" TEST_FILES="op/*.t" =item Parallel tests (並列テスト) =begin original The core distribution can now run its regression tests in parallel on Unix-like platforms. Instead of running C, set C in your environment to the number of tests to run in parallel, and run C. On a Bourne-like shell, this can be done as =end original コア配布は、Unix 風のプラットフォームでは退行テストを並列に 実行できるようになりました。 C を実行する代わりに、並列に実行するテストの数を 環境変数 C に設定して、 C を実行してください。 Bourne 風のシェルでは、これは次のようになります: TEST_JOBS=3 make test_harness # Run 3 tests in parallel =begin original An environment variable is used, rather than parallel make itself, because L needs to be able to schedule individual non-conflicting test scripts itself, and there is no standard interface to C utilities to interact with their job schedulers. =end original 並列 make 自身ではなく環境変数が使われます; L は衝突しないテストスクリプトを自身でスケジュールできる 必要があり、C ユーティリティとこれらのジョブスケジューラを 相互作用させる標準的なインターフェースはないからです。 =begin original Note that currently some test scripts may fail when run in parallel (most notably C). If necessary run just the failing scripts again sequentially and see if the failures go away. =end original 現在の所、並列に実行すると失敗するかもしれないテストがいくつか あることに注意してください (もっとも顕著なものは C)。 もし必要なら、失敗したスクリプトを単に直列に再び実行して、 失敗しなくなるかを見てください。 =item test-notty test_notty =begin original Sets PERL_SKIP_TTY_TEST to true before running normal test. =end original 通常のテストを実行する前に PERL_SKIP_TTY_TEST を真に設定します。 =back =head2 Running tests by hand (手動でテストを実行する) =begin original You can run part of the test suite by hand by using one the following commands from the F directory : =end original F ディレクトリで以下のコマンドの一つを使うことでテストスイートの一部を 手動で実行できます: ./perl -I../lib TEST list-of-.t-files =begin original or =end original または ./perl -I../lib harness list-of-.t-files =begin original (if you don't specify test scripts, the whole test suite will be run.) =end original (テストスクリプトを指定しないと、テストスイート全体が実行されます。) =head3 Using t/harness for testing (テストに t/harness を使う) =begin original If you use C for testing you have several command line options available to you. The arguments are as follows, and are in the order that they must appear if used together. =end original テストに C を使う場合は、いくつかのコマンドラインオプションを 使えます。 引数は次のとおりで、一緒に使った場合に現れなければならない 順序になっています: harness -v -torture -re=pattern LIST OF FILES TO TEST harness -v -torture -re LIST OF PATTERNS TO MATCH =begin original If C is omitted the file list is obtained from the manifest. The file list may include shell wildcards which will be expanded out. =end original C が省略された場合、ファイルリストは マニフェストから取得されます。 ファイルリストにはシェルワイルドカードが含まれている可能性があります。 =over 4 =item -v =begin original Run the tests under verbose mode so you can see what tests were run, and debug output. =end original テストを詳細モードで実行するので、実行されたテストとデバッグ出力を 確認できます。 =item -torture =begin original Run the torture tests as well as the normal set. =end original 通常のセットと同様に拷問テストを実行します。 =item -re=PATTERN =begin original Filter the file list so that all the test files run match PATTERN. Note that this form is distinct from the B<-re LIST OF PATTERNS> form below in that it allows the file list to be provided as well. =end original すべてのテストファイルが PATTERN にマッチングするようにファイルリストを フィルタリングします。 この形式は、ファイルリストも指定できるという点で、次の B<-re LIST OF PATTERNS> 形式とは異なることに注意してください。 =item -re LIST OF PATTERNS =begin original Filter the file list so that all the test files run match /(LIST|OF|PATTERNS)/. Note that with this form the patterns are joined by '|' and you cannot supply a list of files, instead the test files are obtained from the MANIFEST. =end original 実行するすべてのテストファイルが match/(LIST OF PATTERNS)/ に マッチングするようにファイルリストをフィルタリングします。 この形式では、パターンは''で結合され、ファイルのリストを指定できません。 かわりに、テストファイルは MANIFEST から取得されます。 =back =begin original You can run an individual test by a command similar to =end original 次のようなコマンドで、個々のテストを実行できます: ./perl -I../lib patho/to/foo.t =begin original except that the harnesses set up some environment variables that may affect the execution of the test : =end original ただし、ハーネスは、テストの実行に影響を与える可能性のあるいくつかの 環境変数を設定します: =over 4 =item PERL_CORE=1 =begin original indicates that we're running this test part of the perl core test suite. This is useful for modules that have a dual life on CPAN. =end original これは、perl コアテストスイートのこのテスト部分を実行していることを示します。 これは、CPAN上で二重管理されているモジュールに役立ちます。 =item PERL_DESTRUCT_LEVEL=2 =begin original is set to 2 if it isn't set already (see L) =end original まだ設定されていない場合は 2 に設定されます(L を参照)。 =item PERL =begin original (used only by F) if set, overrides the path to the perl executable that should be used to run the tests (the default being F<./perl>). =end original (F でのみ使用)設定されている場合、テストの実行に使う perl 実行可能ファイルへのパスを上書きします(デフォルトは F<./perl>)。 =item PERL_SKIP_TTY_TEST =begin original if set, tells to skip the tests that need a terminal. It's actually set automatically by the Makefile, but can also be forced artificially by running 'make test_notty'. =end original 設定すると、ターミナルが必要なテストを飛ばします。 これは実際には Makefile で自動的に設定されますが、 'make test_notty' を実行して人為的に設定することもできます。 =back =head3 Other environment variables that may influence tests (テストに影響を与えるかも知れないその他の環境変数) =over 4 =item PERL_TEST_Net_Ping =begin original Setting this variable runs all the Net::Ping modules tests, otherwise some tests that interact with the outside world are skipped. See L. =end original この変数を設定すると、すべての Net::Ping モジュールテストが実行されます; そうでない場合、外部世界と対話する一部のテストはスキップされます。 L を参照してください。 =item PERL_TEST_NOVREXX =begin original Setting this variable skips the vrexx.t tests for OS2::REXX. =end original この変数を設定すると、OS2::REXX の vrexx.t テストがスキップされます。 =item PERL_TEST_NUMCONVERTS =begin original This sets a variable in op/numconvert.t. =end original op/numconvert.t に変数を設定します。 =back =begin original See also the documentation for the Test and Test::Harness modules, for more environment variables that affect testing. =end original テストに影響を与える環境変数については、Test および Test::Harness モジュールの文書も参照してください。 =head2 Common problems when patching Perl source code (Perl ソースコードにパッチを当てるときに良くある問題) =begin original Perl source plays by ANSI C89 rules: no C99 (or C++) extensions. In some cases we have to take pre-ANSI requirements into consideration. You don't care about some particular platform having broken Perl? I hear there is still a strong demand for J2EE programmers. =end original Perl ソースは ANSI C89 の規則に従って動作します: C99(または C++)拡張はありません。 場合によっては、ANSI 以前の要件を考慮する必要があります。 特定のプラットフォームが Perl を壊したことに関心はありませんか? J2EE プログラマーに対する需要は依然として強いと聞いています。 =head2 Perl environment problems (Perl 環境の問題) =over 4 =item * =begin original Not compiling with threading =end original スレッドでコンパイルできない =begin original Compiling with threading (-Duseithreads) completely rewrites the function prototypes of Perl. You better try your changes with that. Related to this is the difference between "Perl_-less" and "Perl_-ly" APIs, for example: =end original スレッド化(-Duseithreads) でコンパイルすると、Perl の関数プロトタイプが 完全に書き直されます。 それを使って変更を試してみるとよいでしょう。 これに関連して、"Perl_-less" API と "Perl_-ly" API の違いがあります; 例えば: Perl_sv_setiv(aTHX_ ...); sv_setiv(...); =begin original The first one explicitly passes in the context, which is needed for e.g. threaded builds. The second one does that implicitly; do not get them mixed. If you are not passing in a aTHX_, you will need to do a dTHX (or a dVAR) as the first thing in the function. =end original 最初のものはコンテキストに明示的に渡すもので、 スレッド化ビルドなどに必要です。 2 番目のものは暗黙的に渡します; 混在させないでください。 aTHX_ を渡していない場合は、関数の最初に dTHX(または dVAR) を 行う必要があります。 =begin original See L for further discussion about context. =end original コンテキストの詳細については、 L を 参照してください。 =item * =begin original Not compiling with -DDEBUGGING =end original -DDEBUGGING と一緒にコンパイルできません =begin original The DEBUGGING define exposes more code to the compiler, therefore more ways for things to go wrong. You should try it. =end original DEBUGGING 定義は、より多くのコードをコンパイラに公開するため、問題が 発生する可能性が高くなります。 やってみるといいですよ。 =item * =begin original Introducing (non-read-only) globals =end original (読み取り専用でない)グローバル変数の導入 =begin original Do not introduce any modifiable globals, truly global or file static. They are bad form and complicate multithreading and other forms of concurrency. The right way is to introduce them as new interpreter variables, see F (at the very end for binary compatibility). =end original 真のグローバルやファイル静的など、変更可能なグローバル変数を 導入しないでください。 これらは誤ったな形式であり、マルチスレッドや他の形式の並行性を複雑にします。 正しい方法は、これらを新しいインタプリタ変数として導入することです; Fを参照してください(バイナリ互換性については最後にあります)。 =begin original Introducing read-only (const) globals is okay, as long as you verify with e.g. C (if your C has BSD-style output) that the data you added really is read-only. (If it is, it shouldn't show up in the output of that command.) =end original 例えば C (C がBSD スタイルの出力を 持っている場合)で、追加したデータが本当に読み取り専用であることを 確認すれば、読み取り専用(const)グローバルを導入しても問題ありません (もしそうであれば、このコマンドの出力には現れないはずです。) =begin original If you want to have static strings, make them constant: =end original 静的文字列が必要な場合は、定数にします: static const char etc[] = "..."; =begin original If you want to have arrays of constant strings, note carefully the right combination of Cs: =end original 定数文字列の配列が必要な場合は、C の正しい組み合わせに 注意してください: static const char * const yippee[] = {"hi", "ho", "silver"}; =begin original There is a way to completely hide any modifiable globals (they are all moved to heap), the compilation setting C<-DPERL_GLOBAL_STRUCT_PRIVATE>. It is not normally used, but can be used for testing, read more about it in L. =end original 変更可能なグローバル変数を完全に隠す方法があります(すべてヒープに 移動されます); コンパイル設定は C<-DPERL_GLOBAL_STRUCT_PRIVATE> です。 通常は使われませんが、テストに使うことができます; 詳細は L を読んでください。 =item * =begin original Not exporting your new function =end original 新しい機能をエクスポートしない =begin original Some platforms (Win32, AIX, VMS, OS/2, to name a few) require any function that is part of the public API (the shared Perl library) to be explicitly marked as exported. See the discussion about F in L. =end original 一部のプラットフォーム(Win32、AIX、VMS、OS/2 など)では、パブリック API (共有 Perl ライブラリ)の一部である関数を明示的にエクスポート済みとして マークする必要があります。 L の F に関する説明を参照してください。 =item * =begin original Exporting your new function =end original 新規関数のエクスポート =begin original The new shiny result of either genuine new functionality or your arduous refactoring is now ready and correctly exported. So what could possibly go wrong? =end original これで、真の新機能または困難なリファクタリングによる新しい輝きのある結果が 準備でき、正しくエクスポートされます。 では、何がうまくいかない可能性があるのでしょうか? =begin original Maybe simply that your function did not need to be exported in the first place. Perl has a long and not so glorious history of exporting functions that it should not have. =end original 関数をエクスポートする必要がなかったという単純な理由かもしれません。 Perl には、そうするべきでない関数をエクスポートするという、長くあまり 輝かしくない歴史があります。 =begin original If the function is used only inside one source code file, make it static. See the discussion about F in L. =end original 関数が一つのソースコードファイル内でのみ使われる場合は、関数を静的にします。 L の F に関する説明を参照してください。 =begin original If the function is used across several files, but intended only for Perl's internal use (and this should be the common case), do not export it to the public API. See the discussion about F in L. =end original 関数が複数のファイルにまたがって使われているが、Perl 内部での使用のみを 意図している場合(これは一般的なケースです)は、パブリック API に エクスポートしないでください。 L の F に関する説明を参照してください。 =back =head2 Portability problems (移植性の問題) =begin original The following are common causes of compilation and/or execution failures, not common to Perl as such. The C FAQ is good bedtime reading. Please test your changes with as many C compilers and platforms as possible; we will, anyway, and it's nice to save oneself from public embarrassment. =end original 以下は、コンパイルや実行の失敗の一般的な原因であり、Perl で 一般的というわけではありません。 C FAQは、寝る前に読むのに適しています。 できるだけ多くの C コンパイラとプラットフォームで変更をテストしてください; とにかく、私たちはそうしますし、公の場で恥をかかないようにするのは 良いことです。 =begin original If using gcc, you can add the C<-std=c89> option which will hopefully catch most of these unportabilities. (However it might also catch incompatibilities in your system's header files.) =end original gcc を使っている場合は、C<-std=c89> オプションを追加することができます。 このオプションはこれらの移植性の問題のほとんどをキャッチすることを 期待しています。 (ただし、システムのヘッダファイルの非互換性もキャッチする可能性があります。) =begin original Use the Configure C<-Dgccansipedantic> flag to enable the gcc C<-ansi -pedantic> flags which enforce stricter ANSI rules. =end original より厳密な ANSI 規則を矯正するために gcc の C<-ansi -pedantic> フラグを 有効にするには、Configure の C<-Dgccansipedantic> フラグを使います。 =begin original If using the C note that not all the possible warnings (like C<-Wunitialized>) are given unless you also compile with C<-O>. =end original C を使っている場合は、C<-O> も付けてコンパイルしない限り、 (C<-Wunitialized> のような)考えられるすべての警告が 表示されるわけではないことに注意してください。 =begin original Note that if using gcc, starting from Perl 5.9.5 the Perl core source code files (the ones at the top level of the source code distribution, but not e.g. the extensions under ext/) are automatically compiled with as many as possible of the C<-std=c89>, C<-ansi>, C<-pedantic>, and a selection of C<-W> flags (see cflags.SH). =end original gcc を使っている場合、Perl 5.9.5 以降では、Perl コアソースコードファイル (ソースコード配布物の最上位レベルにあるもので、ext/ の下の拡張部分などは 含まれません)は、自動的に、できるだけ多くの C<-std=c89>、C<-ansi>、C<-pedantic>、そしていくつかの C<-W> フラグ (cflags.SH を参照) とともにコンパイルされます。 =begin original Also study L carefully to avoid any bad assumptions about the operating system, filesystems, and so forth. =end original また、L を注意深く研究して、オペレーティングシステムや ファイルシステムなどに関する誤った仮定を避けるようにしてください。 =begin original You may once in a while try a "make microperl" to see whether we can still compile Perl with just the bare minimum of interfaces. (See README.micro.) =end original 必要最小限のインターフェースで Perl をコンパイルできるかどうか、 "make microperl" を試してみてください(README.microを参照。)。 =begin original Do not assume an operating system indicates a certain compiler. =end original あるオペレーティングシステムが特定のコンパイラを示すことを 仮定しないでください。 =over 4 =item * =begin original Casting pointers to integers or casting integers to pointers =end original ポインタを整数にキャストしたり整数をポインタにキャストしたりする void castaway(U8* p) { IV i = p; =begin original or =end original または void castaway(U8* p) { IV i = (IV)p; =begin original Both are bad, and broken, and unportable. Use the PTR2IV() macro that does it right. (Likewise, there are PTR2UV(), PTR2NV(), INT2PTR(), and NUM2PTR().) =end original どちらも悪く、壊れていて、移植性がありません。 これを正しく行うためには PTR2IV() マクロを使ってください。 (同様に、PTR2UV(), PTR2NV(), INT2PTR(), NUM2PTR() があります。) =item * =begin original Casting between data function pointers and data pointers =end original データ関数ポインタとデータポインタの間でキャストする =begin original Technically speaking casting between function pointers and data pointers is unportable and undefined, but practically speaking it seems to work, but you should use the FPTR2DPTR() and DPTR2FPTR() macros. Sometimes you can also play games with unions. =end original 関数ポインタとデータポインタの間のキャストは、技術的には移植性がなく 定義されていませんが、実際には動作しているように見えますが、 FPTR2DPTR() と DPTR2FPTR() マクロを使うべきです。 共用体とゲームをすることもできます。 =item * =begin original Assuming sizeof(int) == sizeof(long) =end original sizeof(int) == sizeof(long) と仮定する =begin original There are platforms where longs are 64 bits, and platforms where ints are 64 bits, and while we are out to shock you, even platforms where shorts are 64 bits. This is all legal according to the C standard. (In other words, "long long" is not a portable way to specify 64 bits, and "long long" is not even guaranteed to be any wider than "long".) =end original long が 64 ビットであるプラットフォームと int が 64 ビットである プラットフォームがあり、私たちは驚かされますが、short が 64 ビットである プラットフォームもあります。 これは C 標準に従ってすべて合法です(言い換えれば、"long long" は 64 ビットを 指定する移植可能な方法ではなく、"long long"は"long"よりも広いことさえ 保証されません)。 =begin original Instead, use the definitions IV, UV, IVSIZE, I32SIZE, and so forth. Avoid things like I32 because they are B guaranteed to be I 32 bits, they are I 32 bits, nor are they guaranteed to be B or B. If you really explicitly need 64-bit variables, use I64 and U64, but only if guarded by HAS_QUAD. =end original 代わりに、IV, UV, IVSIZE, I32SIZE などの定義を使ってください。 I32 のようなものは、I<正確に> 32 ビットであること、 I<少なくとも> 32ビットであることが保証されて B<いません>; B や B であることも保証されていません。 本当に明示的に 64 ビット変数が必要な場合は、HAS_QUAD で 保護されている場合に限り、I64 と U64 を使ってください。 =item * =begin original Assuming one can dereference any type of pointer for any type of data =end original 任意の型のデータのために任意の型のポインタをデリファレンスできると仮定する char *p = ...; long pony = *p; /* BAD */ =begin original Many platforms, quite rightly so, will give you a core dump instead of a pony if the p happens not be correctly aligned. =end original 多くのプラットフォームでは、それが正しいのですが、p が正しい アライメントでなければ、pony ではなくコアダンプを出力します。 =item * =begin original Lvalue casts =end original 左辺値をキャストする (int)*p = ...; /* BAD */ =begin original Simply not portable. Get your lvalue to be of the right type, or maybe use temporary variables, or dirty tricks with unions. =end original 単に移植性がありません。 左辺値を適切な型にするか、あるいは一時的な変数を使うか、または 共用体で汚いトリックを使うかもしれません。 =item * =begin original Assume B about structs (especially the ones you don't control, like the ones coming from the system headers) =end original 構造体について (特にシステムヘッダのような制御できないものについて) B<何かを> 仮定する =over 8 =item * =begin original That a certain field exists in a struct =end original 構造体にある特定のフィールドがある =item * =begin original That no other fields exist besides the ones you know of =end original わかっているものの他にフィールドがない =item * =begin original That a field is of certain signedness, sizeof, or type =end original あるフィールドの符号有り無し、sizeof、型 =item * =begin original That the fields are in a certain order =end original フィールドが特定の順序で並んでいる =over 8 =item * =begin original While C guarantees the ordering specified in the struct definition, between different platforms the definitions might differ =end original C は struct 定義で指定された順に並んでいることを保証していますが、異なった プラットフォーム絵は定義が異なるかもしれません =back =item * =begin original That the sizeof(struct) or the alignments are the same everywhere =end original sizeof(struct) やアライメントがどこでも同じである =over 8 =item * =begin original There might be padding bytes between the fields to align the fields - the bytes can be anything =end original フィールドの位置合わせにフィールドの間にパッディングのバイトが あるかもしれません - バイトはなんでもかまいません =item * =begin original Structs are required to be aligned to the maximum alignment required by the fields - which for native types is for usually equivalent to sizeof() of the field =end original 構造体は、フィールドで要求される最大のアラインメントに合わせる必要があります - ネイティブ型では、これは通常、フィールドの sizeof() に相当します =back =back =item * =begin original Assuming the character set is ASCIIish =end original 文字集合が ASCII 風であると仮定する =begin original Perl can compile and run under EBCDIC platforms. See L. This is transparent for the most part, but because the character sets differ, you shouldn't use numeric (decimal, octal, nor hex) constants to refer to characters. You can safely say 'A', but not 0x41. You can safely say '\n', but not \012. If a character doesn't have a trivial input form, you can create a #define for it in both C and C, so that it resolves to different values depending on the character set being used. (There are three different EBCDIC character sets defined in C, so it might be best to insert the #define three times in that file.) =end original Perl は EBCDIC プラットフォームでコンパイルおよび実行できます。 L を参照してください。 これはほとんどの部分で透過的ですが、文字集合が異なるため、文字を 参照するために数値定数(10 進数、8 進数、16 進数)を使うべきではありません。 'A' は安全に言うことはできますが、0x41 はできません。 '\n' は安全に言うことはできますが、\012 はできません。 文字に簡単な入力形式がない場合は、C と C の両方で #define を作成して、使われている文字集合に応じて異なる値に 解決することができます。 (C では三つの異なる EBCDIC 文字集合が定義されているので、 そのファイルに #define を 3 回挿入することをお勧めします。) =begin original Also, the range 'A' - 'Z' in ASCII is an unbroken sequence of 26 upper case alphabetic characters. That is not true in EBCDIC. Nor for 'a' to 'z'. But '0' - '9' is an unbroken range in both systems. Don't assume anything about other ranges. =end original また、ASCII の 'A'-'Z' の範囲は、26 個の大文字アルファベット文字の 連続したものです。 EBCDIC ではそうではありません。 また、'a' か ら'z' も同様です。 しかし、'0'-'9' は両方のシステムで連続した範囲です。 他の範囲について何も仮定しないでください。 =begin original Many of the comments in the existing code ignore the possibility of EBCDIC, and may be wrong therefore, even if the code works. This is actually a tribute to the successful transparent insertion of being able to handle EBCDIC without having to change pre-existing code. =end original 既存のコードのコメントの多くは EBCDIC の可能性を無視しているため、コードが 動作しても間違っている可能性があります。 これは実際には、既存のコードを変更することなく EBCDIC を処理できる 透過的な挿入が成功したことへの賛辞です。 =begin original UTF-8 and UTF-EBCDIC are two different encodings used to represent Unicode code points as sequences of bytes. Macros with the same names (but different definitions) in C and C are used to allow the calling code to think that there is only one such encoding. This is almost always referred to as C, but it means the EBCDIC version as well. Again, comments in the code may well be wrong even if the code itself is right. For example, the concept of C differs between ASCII and EBCDIC. On ASCII platforms, only characters that do not have the high-order bit set (i.e. whose ordinals are strict ASCII, 0 - 127) are invariant, and the documentation and comments in the code may assume that, often referring to something like, say, C. The situation differs and is not so simple on EBCDIC machines, but as long as the code itself uses the C macro appropriately, it works, even if the comments are wrong. =end original UTF-8 と UTF-EBCDIC は、Unicode 符号位置をバイト列として 表現するために使われる二つの異なるエンコーディングです。 C と C で同じ名前(ただし定義が異なる)を持つマクロは、 呼び出し側のコードにそのようなエンコーディングが一つしかないと 認識させるために使われます。 これはほとんど常に C と呼ばれていますが、EBCDIC 版も意味します。 繰り返しますが、コード内のコメントは、コード自体が正しい場合でも 間違っている可能性があります。 たとえば、C の概念は ASCII と EBCDIC で異なります。 ASCII プラットフォームでは、上位ビットセットを持たない文字(つまり、その序数が 厳密な ASCII、0-127)のみが不変であり、コード内の文書とコメントは、 しばしば C のようなものを参照していると想定することができます。 状況は異なり、EBCDIC マシンではそれほど単純ではありませんが、コード自体が C マクロを適切に使っている限り、コメントが 間違っていても機能します。 =item * =begin original Assuming the character set is just ASCII =end original 文字集合が単に ASCII であると仮定する =begin original ASCII is a 7 bit encoding, but bytes have 8 bits in them. The 128 extra characters have different meanings depending on the locale. Absent a locale, currently these extra characters are generally considered to be unassigned, and this has presented some problems. This is being changed starting in 5.12 so that these characters will be considered to be Latin-1 (ISO-8859-1). =end original ASCII は 7 ビットエンコーディングですが、バイトには 8 ビットが含まれています。 128 個の余分な文字は、ロケールによって異なる意味を持ちます。 ロケールが存在しない場合、現在これらの余分な文字は一般的に 割り当てられていないと考えられているため、いくつかの問題が発生しています。 これは 5.12 に変更され、これらの文字は Latin-1(ISO-8859-1) と 見なされるようになります。 =item * =begin original Mixing #define and #ifdef =end original #define と #ifdef を混ぜる #define BURGLE(x) ... \ #ifdef BURGLE_OLD_STYLE /* BAD */ ... do it the old way ... \ #else ... do it the new way ... \ #endif =begin original You cannot portably "stack" cpp directives. For example in the above you need two separate BURGLE() #defines, one for each #ifdef branch. =end original 移植性のある方法で cpp 指示子を「スタック」させることはできません。 上述の例では、#ifdef の分岐毎に一つ、計二つの別々の BURGLE() の #define が 必要です。 =item * =begin original Adding non-comment stuff after #endif or #else =end original #endif または #else の後にコメント以外の内容を追加する #ifdef SNOSH ... #else !SNOSH /* BAD */ ... #endif SNOSH /* BAD */ =begin original The #endif and #else cannot portably have anything non-comment after them. If you want to document what is going (which is a good idea especially if the branches are long), use (C) comments: =end original #endif と #else は、その後ろにコメント以外のものを書くと移植性がありません。 何をしているかを書いておきたい場合(これは特に分岐が長いときにはよい 考えです)、(C の)コメントを使います: #ifdef SNOSH ... #else /* !SNOSH */ ... #endif /* SNOSH */ =begin original The gcc option C<-Wendif-labels> warns about the bad variant (by default on starting from Perl 5.9.4). =end original gcc オプション C<-Wendif-labels> は悪い変形について警告します (Perl 5.9.4 からこれはデフォルトです)。 =item * =begin original Having a comma after the last element of an enum list =end original enum リストの最後の要素の後ろにカンマを付ける enum color { CERULEAN, CHARTREUSE, CINNABAR, /* BAD */ }; =begin original is not portable. Leave out the last comma. =end original は移植性はありません。 最後のカンマは省いてください。 =begin original Also note that whether enums are implicitly morphable to ints varies between compilers, you might need to (int). =end original また、enum が暗黙に int に変換されるかどうかはコンパイラによって異なることに 注意してください; (int) する必要があるかもしれません。 =item * =begin original Using //-comments =end original // コメントを使う // This function bamfoodles the zorklator. /* BAD */ =begin original That is C99 or C++. Perl is C89. Using the //-comments is silently allowed by many C compilers but cranking up the ANSI C89 strictness (which we like to do) causes the compilation to fail. =end original これは C99 または C++ です。 Perl は C89 です。 //-コメントを使うことは多くの C コンパイラで暗黙的に許可されていますが、 ANSI C89 の厳密さを強化してしまうと(私たちがやりたいことですが) コンパイルが失敗します。 =item * =begin original Mixing declarations and code =end original 宣言とコードを混ぜる void zorklator() { int n = 3; set_zorkmids(n); /* BAD */ int q = 4; =begin original That is C99 or C++. Some C compilers allow that, but you shouldn't. =end original これは C99 または C++ です。 一部の C コンパイラはこれを使えますが、するべきではありません。 =begin original The gcc option C<-Wdeclaration-after-statements> scans for such problems (by default on starting from Perl 5.9.4). =end original gcc オプション C<-Wdeclaration-after-statements> はこのような問題を スキャンします (Perl 5.9.4 からデフォルトです)。 =item * =begin original Introducing variables inside for() =end original for() 内部の変数を導入する for(int i = ...; ...; ...) { /* BAD */ =begin original That is C99 or C++. While it would indeed be awfully nice to have that also in C89, to limit the scope of the loop variable, alas, we cannot. =end original これは C99 または C++ です。 ループ変数を制限するために C89 でもできれば本当にとてもよいことなのですが、 悲しいかなそれはできません。 =item * =begin original Mixing signed char pointers with unsigned char pointers =end original 符号付き char ポインタと符号なし char ポインタを混ぜる int foo(char *s) { ... } ... unsigned char *t = ...; /* Or U8* t = ... */ foo(t); /* BAD */ =begin original While this is legal practice, it is certainly dubious, and downright fatal in at least one platform: for example VMS cc considers this a fatal error. One cause for people often making this mistake is that a "naked char" and therefore dereferencing a "naked char pointer" have an undefined signedness: it depends on the compiler and the flags of the compiler and the underlying platform whether the result is signed or unsigned. For this very same reason using a 'char' as an array index is bad. =end original これは法的慣行ではありますが、確かに疑わしく、少なくとも一つの プラットフォームでは致命的です: 例えばVMS cc はこれを致命的エラーと 見なします。 人々がこの間違いを頻繁にする原因の一つは、"naked char"、したがって "naked char pointer" を逆参照する場合の符号が未定義であることです: 結果が符号付きか符号なしかは、コンパイラとコンパイラ基盤となる プラットフォームのフラグに依存します。 これとまったく同じ理由で、'char' を配列インデックスとして使うのは 不適切です。 =item * =begin original Macros that have string constants and their arguments as substrings of the string constants =end original 文字列定数とその引数を文字列定数の部分文字列として持つマクロ #define FOO(n) printf("number = %d\n", n) /* BAD */ FOO(10); =begin original Pre-ANSI semantics for that was equivalent to =end original このための ANSI 以前の構文は次のものです: printf("10umber = %d\10"); =begin original which is probably not what you were expecting. Unfortunately at least one reasonably common and modern C compiler does "real backward compatibility" here, in AIX that is what still happens even though the rest of the AIX compiler is very happily C89. =end original これはおそらくあなたが期待していたものではありません。 残念ながら、少なくとも一つの合理的に一般的で最新のCコンパイラが、 ここでは「真の後方互換性」を実現しています; AIX では、AIX コンパイラの残りの部分が非常に幸せに C89 であっても、これが 依然として行われています。 =item * =begin original Using printf formats for non-basic C types =end original 基本 C 型以外の printf のフォーマットを使う IV i = ...; printf("i = %d\n", i); /* BAD */ =begin original While this might by accident work in some platform (where IV happens to be an C), in general it cannot. IV might be something larger. Even worse the situation is with more specific types (defined by Perl's configuration step in F): =end original これはいくつかの(IV がたまたま C であるような)プラットフォームでは 偶然動作するかもしれませんが、一般的にはこれはできません。 IV はもっと大きいかもしれません。 もっと悪いことに、この状況はより特定の (F にある Perl の設定 ステップで定義される)型です: Uid_t who = ...; printf("who = %d\n", who); /* BAD */ =begin original The problem here is that Uid_t might be not only not C-wide but it might also be unsigned, in which case large uids would be printed as negative values. =end original ここでの問題は、Uid_t が C 幅でないだけでなく、符号なしでもある 可能性があることであり、その場合、大きな uid は負の値として出力されます。 =begin original There is no simple solution to this because of printf()'s limited intelligence, but for many types the right format is available as with either 'f' or '_f' suffix, for example: =end original printf() のインテリジェンスが限られているため、これに対する簡単な解決策は ありませんが、多くの型では 'f' または '_f' 接尾辞のような適切な フォーマットが利用できます; 例えば: IVdf /* IV in decimal */ UVxf /* UV is hexadecimal */ printf("i = %"IVdf"\n", i); /* The IVdf is a string constant. */ Uid_t_f /* Uid_t in decimal */ printf("who = %"Uid_t_f"\n", who); =begin original Or you can try casting to a "wide enough" type: =end original または、「十分に広い」型にキャストすることもできます: printf("i = %"IVdf"\n", (IV)something_very_small_and_signed); =begin original Also remember that the C<%p> format really does require a void pointer: =end original C<%p> フォーマットは実際は void ポインタが必要であることも 忘れないでください: U8* p = ...; printf("p = %p\n", (void*)p); =begin original The gcc option C<-Wformat> scans for such problems. =end original gcc オプション C<-Wformat> はこのような問題をスキャンします。 =item * =begin original Blindly using variadic macros =end original 可変マクロの盲目的な使用 =begin original gcc has had them for a while with its own syntax, and C99 brought them with a standardized syntax. Don't use the former, and use the latter only if the HAS_C99_VARIADIC_MACROS is defined. =end original gcc には独自の構文があり、C99 には標準化された構文があります。 前者は使わず、後者は HAS_C99_VARIADIC_MACROS が定義されている場合にのみ 使ってください。 =item * =begin original Blindly passing va_list =end original 盲目的に va_list を渡す =begin original Not all platforms support passing va_list to further varargs (stdarg) functions. The right thing to do is to copy the va_list using the Perl_va_copy() if the NEED_VA_COPY is defined. =end original すべてのプラットフォームが va_list を他の varargs(stdarg) 関数に渡すことを サポートしているわけではありません。 NEED_VA_COPY が定義されている場合は、Perl_va_copy() を使って va_list を コピーするのが適切です。 =item * =begin original Using gcc statement expressions =end original gcc 文表現を使う val = ({...;...;...}); /* BAD */ =begin original While a nice extension, it's not portable. The Perl code does admittedly use them if available to gain some extra speed (essentially as a funky form of inlining), but you shouldn't. =end original よい拡張ではありますが、移植性がありません。 Perl コードでは(本質的には変わった形のインラインとして)より速度が 得られる場合には使っているのは確かですが、あなたはするべきではありません。 =item * =begin original Binding together several statements in a macro =end original マクロの中で複数の文を結び付ける =begin original Use the macros STMT_START and STMT_END. =end original マクロ STMT_START と STMT_END を使ってください。 STMT_START { ... } STMT_END =item * =begin original Testing for operating systems or versions when should be testing for features =end original 機能をテストするべきところでオペレーティングシステムやバージョンをテストする #ifdef __FOONIX__ /* BAD */ foo = quux(); #endif =begin original Unless you know with 100% certainty that quux() is only ever available for the "Foonix" operating system B that is available B correctly working for B past, present, B future versions of "Foonix", the above is very wrong. This is more correct (though still not perfect, because the below is a compile-time check): =end original quux() が "Foonix" オペレーティングシステムでのみ利用可能であり、B<かつ> これが "Foonix"の過去、現在、将来の B<全ての> バージョンで利用可能で、 B<かつ> 正しく動作することを 100% 確実に知っていない限り、 上記は非常に間違っています。 次のものはより正確です(これはコンパイル時チェックなので、まだ 完全ではありませんが): #ifdef HAS_QUUX foo = quux(); #endif =begin original How does the HAS_QUUX become defined where it needs to be? Well, if Foonix happens to be Unixy enough to be able to run the Configure script, and Configure has been taught about detecting and testing quux(), the HAS_QUUX will be correctly defined. In other platforms, the corresponding configuration step will hopefully do the same. =end original HAS_QUUX は必要な場所でどのように定義されるのでしょうか? まあ、もし Foonix が Configure スクリプトを実行するのに十分ななくらい Unixy であり、Configure が quux() の検出とテストについて教えられているなら、 HAS_QUUX は正しく定義されるでしょう。 他のプラットフォームでは、対応する設定ステップが同じことをすることを 期待しています。 =begin original In a pinch, if you cannot wait for Configure to be educated, or if you have a good hunch of where quux() might be available, you can temporarily try the following: =end original 困ったときに、Configure が教育されるのを待てない場合や、quux() が どこで使えるか予感がある場合には、一時的に以下を試すことができます: #if (defined(__FOONIX__) || defined(__BARNIX__)) # define HAS_QUUX #endif ... #ifdef HAS_QUUX foo = quux(); #endif =begin original But in any case, try to keep the features and operating systems separate. =end original ただし、いずれの場合でも、機能とオペレーティングシステムを 分離するようにしてください。 =back =head2 Problematic System Interfaces (問題のあるシステムインターフェース) =over 4 =item * =begin original malloc(0), realloc(0), calloc(0, 0) are non-portable. To be portable allocate at least one byte. (In general you should rarely need to work at this low level, but instead use the various malloc wrappers.) =end original malloc(0), realloc(0), calloc(0, 0) は移植性がありません。 移植性を持たせるためには、少なくとも 1 バイトを割り当ててください。 (一般に、この低レベルで作業する必要はほとんどありません; 代わりに さまざまな malloc ラッパーを使ってください。) =item * =begin original snprintf() - the return type is unportable. Use my_snprintf() instead. =end original snprintf() - 返り型は移植性がありません。 代わりに my_snprintf() を使ってください。 =back =head2 Security problems (セキュリティ問題) =begin original Last but not least, here are various tips for safer coding. =end original 最後ですが重要な、より安全なコーディングのためのさまざまなヒントを 紹介します。 =over 4 =item * =begin original Do not use gets() =end original gets() を使わない =begin original Or we will publicly ridicule you. Seriously. =end original さもなければ私たちは公にあなたをからかうことになるでしょう。 本気です。 =item * =begin original Do not use strcpy() or strcat() or strncpy() or strncat() =end original strcpy(), strcat(), strncpy(), strncat() を使わない =begin original Use my_strlcpy() and my_strlcat() instead: they either use the native implementation, or Perl's own implementation (borrowed from the public domain implementation of INN). =end original 代わりに my_strlcpy() と my_strlcat() を使ってください: これらはネイティブな実装か、Perl 独自の実装(INN の パブリックドメイン実装から借用したもの)を使います。 =item * =begin original Do not use sprintf() or vsprintf() =end original sprintf(), vsprintf() を使わない =begin original If you really want just plain byte strings, use my_snprintf() and my_vsnprintf() instead, which will try to use snprintf() and vsnprintf() if those safer APIs are available. If you want something fancier than a plain byte string, use SVs and Perl_sv_catpvf(). =end original 本当にプレーンなバイト文字列だけが必要な場合は、代わりに my_snprintf() と y_vsnprintf() を使ってください; これらは、より安全な API が利用可能であれば、snprintf() と vsnprintf() を 使おうとします。 プレーンなバイト文字列よりも洗練されたものが必要な場合は、 SV と Perl_sv_catpvf() を使ってください。 =back =head1 EXTERNAL TOOLS FOR DEBUGGING PERL (Perl をデバッグするための外部ツール) =begin original Sometimes it helps to use external tools while debugging and testing Perl. This section tries to guide you through using some common testing and debugging tools with Perl. This is meant as a guide to interfacing these tools with Perl, not as any kind of guide to the use of the tools themselves. =end original Perlをデバッグしたりテストしたりするときに、外部ツールを使うと 便利な場合があります。 このセクションでは、一般的なテストツールやデバッグツールを Perl で使う方法を 説明します。 これは、これらのツールを Perl と繋ぐためのガイドであり、 ツール自体を使うためのガイドではありません。 =begin original B: Running under memory debuggers such as Purify, valgrind, or Third Degree greatly slows down the execution: seconds become minutes, minutes become hours. For example as of Perl 5.8.1, the ext/Encode/t/Unicode.t takes extraordinarily long to complete under e.g. Purify, Third Degree, and valgrind. Under valgrind it takes more than six hours, even on a snappy computer. The said test must be doing something that is quite unfriendly for memory debuggers. If you don't feel like waiting, that you can simply kill away the perl process. =end original B<注 1>: Purify, Valgrind, Third Degree などのメモリデバッガで実行すると、 実行速度が大幅に低下します: 秒は分になり、分は時間になります。 たとえば、Perl 5.8.1 では、ext/Encode/t/Unicode.t は、Purify, Third Degree, Valgrind などで実行すると非常に時間がかかります。 Valgrind では、高速なコンピュータでも 6 時間以上かかります。 このテストは、メモリデバッガにとって非常に扱いにくいことを 行っているはずです。 待つ気がなければ、perl プロセスを kill するだけで済みます。 =begin original B: To minimize the number of memory leak false alarms (see L for more information), you have to set the environment variable PERL_DESTRUCT_LEVEL to 2. =end original B<注 2>: メモリリークの誤通知 (詳細については L を 参照) の数を最小限にするためには、環境変数 PERL_DESTRUCT_LEVEL を 2 に 設定する必要があります。 =begin original For csh-like shells: =end original csh のようなシェルの場合: setenv PERL_DESTRUCT_LEVEL 2 =begin original For Bourne-type shells: =end original Bourne タイプのシェルの場合: PERL_DESTRUCT_LEVEL=2 export PERL_DESTRUCT_LEVEL =begin original In Unixy environments you can also use the C command: =end original UNIXy 環境では、C コマンドを使うこともできます: env PERL_DESTRUCT_LEVEL=2 valgrind ./perl -Ilib ... =begin original B: There are known memory leaks when there are compile-time errors within eval or require, seeing C in the call stack is a good sign of these. Fixing these leaks is non-trivial, unfortunately, but they must be fixed eventually. =end original B<注 3>: eval または require 内にコンパイル時エラーがある場合、既知の メモリリークがあります; コールスタックに C があることは、これらの良い兆候です。 残念ながら、これらのリークを修正することは簡単ではありませんが、最終的には 修正する必要があります。 =begin original B: L will not clean up after itself completely unless Perl is built with the Configure option C<-Accflags=-DDL_UNLOAD_ALL_AT_EXIT>. =end original B<注 4>:Perl が Configure オプション C<-Accflags=-DDL_UNLOAD_ALL_AT_EXIT> で構築されていない限り、 L は自分自身を完全にクリーンアップすることはありません。 =head2 Rational Software's Purify (Rational Software の Purify) =begin original Purify is a commercial tool that is helpful in identifying memory overruns, wild pointers, memory leaks and other such badness. Perl must be compiled in a specific way for optimal testing with Purify. Purify is available under Windows NT, Solaris, HP-UX, SGI, and Siemens Unix. =end original Purify は、メモリオーバーラン、ワイルドポインタ、メモリリークなどの不良を 識別するのに役立つ商用ツールです。 Purify で最適なテストを行うためには、Perl を特定の方法でコンパイルする 必要があります。 Purify は Windows NT, Solaris, HP-UX, SGI, Siemens Unix で利用できます。 =head2 Purify on Unix (Unix での Purify) =begin original On Unix, Purify creates a new Perl binary. To get the most benefit out of Purify, you should create the perl to Purify using: =end original Unix では、Purify は新しい Perl バイナリを作成します。 Purify を最大限に活用するには、以下を使って Purify 用の perl を作成する 必要があります: sh Configure -Accflags=-DPURIFY -Doptimize='-g' \ -Uusemymalloc -Dusemultiplicity =begin original where these arguments mean: =end original これらの引数の意味は次のとおりです: =over 4 =item -Accflags=-DPURIFY =begin original Disables Perl's arena memory allocation functions, as well as forcing use of memory allocation functions derived from the system malloc. =end original Perl のアリーナメモリ割り当て関数を無効にし、システム malloc から派生した メモリ割り当て関数を強制的に使います。 =item -Doptimize='-g' =begin original Adds debugging information so that you see the exact source statements where the problem occurs. Without this flag, all you will see is the source filename of where the error occurred. =end original デバッグ情報を追加して、問題が発生したソース文を正確に表示します。 このフラグがなければ、エラーが発生したソースファイル名だけが表示されます。 =item -Uusemymalloc =begin original Disable Perl's malloc so that Purify can more closely monitor allocations and leaks. Using Perl's malloc will make Purify report most leaks in the "potential" leaks category. =end original Perl の malloc を無効にして、Purify が割り当てとリークをより厳密に 監視できるようにします。 Perl の malloc を使うと、Purify は「潜在的な」リークのカテゴリで最も多くの リークをレポートします。 =item -Dusemultiplicity =begin original Enabling the multiplicity option allows perl to clean up thoroughly when the interpreter shuts down, which reduces the number of bogus leak reports from Purify. =end original multiplicity オプションを有効にすると、perl はインタプリタが シャットダウンしたときに完全にクリーンアップすることができ、 Purify からの偽のリークレポートの数を減らすことができます。 =back =begin original Once you've compiled a perl suitable for Purify'ing, then you can just: =end original Purify に適した Perl をコンパイルしたら、次のようにします: make pureperl =begin original which creates a binary named 'pureperl' that has been Purify'ed. This binary is used in place of the standard 'perl' binary when you want to debug Perl memory problems. =end original Purify された "pureperl" という名前のバイナリを作成します。 このバイナリは、Perl メモリの問題をデバッグしたい場合に、標準の "perl" バイナリの代わりに使われます。 =begin original As an example, to show any memory leaks produced during the standard Perl testset you would create and run the Purify'ed perl as: =end original たとえば、標準的な Perl テストセットで生成されたメモリリークを 表示するには、Purify の perl を次のように作成して実行します: make pureperl cd t ../pureperl -I../lib harness =begin original which would run Perl on test.pl and report any memory problems. =end original test.pl で Perl を実行し、メモリの問題を報告します。 =begin original Purify outputs messages in "Viewer" windows by default. If you don't have a windowing environment or if you simply want the Purify output to unobtrusively go to a log file instead of to the interactive window, use these following options to output to the log file "perl.log": =end original デフォルトでは、Purify は "Viewer" ウィンドウにメッセージを出力します。 ウィンドウ環境がない場合、または Purify 出力を対話式ウィンドウではなく 控えめなログファイルに出力する場合は、次のオプションを使ってログファイル "perl.log" に出力します: setenv PURIFYOPTIONS "-chain-length=25 -windows=no \ -log-file=perl.log -append-logfile=yes" =begin original If you plan to use the "Viewer" windows, then you only need this option: =end original "Viewer" ウィンドウを使う場合は、次のオプションのみが必要です: setenv PURIFYOPTIONS "-chain-length=25" =begin original In Bourne-type shells: =end original Bourne タイプのシェルの場合: PURIFYOPTIONS="..." export PURIFYOPTIONS =begin original or if you have the "env" utility: =end original "env" ユーティリティを使っている場合: env PURIFYOPTIONS="..." ../pureperl ... =head2 Purify on NT (NT での Purify) =begin original Purify on Windows NT instruments the Perl binary 'perl.exe' on the fly. There are several options in the makefile you should change to get the most use out of Purify: =end original Purify on Windows NT では、Perl バイナリ 'perl.exe' をオンザフライで 計測します。 Purify を最大限に活用するためには、makefile のいくつかのオプションを 変更する必要があります。 =over 4 =item DEFINES =begin original You should add -DPURIFY to the DEFINES line so the DEFINES line looks something like: =end original DEFINES 行に -DPURIFY を追加して、DEFINES 行が次のようになるようにします。 DEFINES = -DWIN32 -D_CONSOLE -DNO_STRICT $(CRYPT_FLAG) -DPURIFY=1 =begin original to disable Perl's arena memory allocation functions, as well as to force use of memory allocation functions derived from the system malloc. =end original Perl のアリーナメモリアロケーション関数を無効にしたり、malloc システムから 派生したメモリアロケーション関数を強制的に使わせたりします。 =item USE_MULTI = define =begin original Enabling the multiplicity option allows perl to clean up thoroughly when the interpreter shuts down, which reduces the number of bogus leak reports from Purify. =end original multiplicity オプションを有効にすると、perl はインタプリタが シャットダウンしたときに完全にクリーンアップすることができ、 Purify からの偽のリークレポートの数を減らすことができます。 =item #PERL_MALLOC = define =begin original Disable Perl's malloc so that Purify can more closely monitor allocations and leaks. Using Perl's malloc will make Purify report most leaks in the "potential" leaks category. =end original Perl の malloc を無効にして、Purify が割り当てとリークをより厳密に 監視できるようにします。 Perl の malloc を使うと、Purify は「潜在的な」リークのカテゴリで最も多くの リークをレポートします。 =item CFG = Debug =begin original Adds debugging information so that you see the exact source statements where the problem occurs. Without this flag, all you will see is the source filename of where the error occurred. =end original デバッグ情報を追加して、問題が発生したソース文を正確に表示します。 このフラグがなければ、エラーが発生したソースファイル名だけが表示されます。 =back =begin original As an example, to show any memory leaks produced during the standard Perl testset you would create and run Purify as: =end original 例として、標準 Perl テストセット中に生成されたメモリリークを表示するために、 Purify を次のように作成して実行します: cd win32 make cd ../t purify ../perl -I../lib harness =begin original which would instrument Perl in memory, run Perl on test.pl, then finally report any memory problems. =end original メモリに Perl を構築し、test.pl 上で Perl を実行し、最後にメモリの問題を 報告します。 =head2 valgrind =begin original The excellent valgrind tool can be used to find out both memory leaks and illegal memory accesses. As of version 3.3.0, Valgrind only supports Linux on x86, x86-64 and PowerPC. The special "test.valgrind" target can be used to run the tests under valgrind. Found errors and memory leaks are logged in files named F. =end original 優れた valgrind ツールは、メモリリークと不正なメモリアクセスの両方を 見つけるために使えます。 バージョン 3.3.0 では、Valgrind は x86、x86-64、および PowerPC 上の Linux のみをサポートしています。 特別な "test.valgrind" ターゲットを使って、valgrind 下でテストを実行できます。 検出されたエラーとメモリリークは、F という名前の ファイルに記録されます。 =begin original Valgrind also provides a cachegrind tool, invoked on perl as: =end original Valgrind は cachegrind ツールも提供しており、perl で以下のように 呼び出されます: VG_OPTS=--tool=cachegrind make test.valgrind =begin original As system libraries (most notably glibc) are also triggering errors, valgrind allows to suppress such errors using suppression files. The default suppression file that comes with valgrind already catches a lot of them. Some additional suppressions are defined in F. =end original システムライブラリ(最も顕著な glibc)もエラーを引き起こすので、valgrind は 抑制ファイルを使ってそのようなエラーを抑制することができます。 valgrind に付属のデフォルトの抑制ファイルはすでに多くのエラーを捕捉しています。 いくつかの追加の抑制は F で定義されています。 =begin original To get valgrind and for more information see =end original 詳細については、以下を参照してください: http://developer.kde.org/~sewardj/ =head2 Compaq's/Digital's/HP's Third Degree (Compaq/Digital/HP の Third Degree) =begin original Third Degree is a tool for memory leak detection and memory access checks. It is one of the many tools in the ATOM toolkit. The toolkit is only available on Tru64 (formerly known as Digital UNIX formerly known as DEC OSF/1). =end original Third Degree は、メモリリーク検出とメモリアクセスチェックのためのツールです。 これは ATOM ツールキットに含まれる多くのツールの一つです。 このツールキットは (以前は DEC OSF/1 として知られていた Digital UNIX として 知られていた) Tru64 でのみ使えます。 =begin original When building Perl, you must first run Configure with -Doptimize=-g and -Uusemymalloc flags, after that you can use the make targets "perl.third" and "test.third". (What is required is that Perl must be compiled using the C<-g> flag, you may need to re-Configure.) =end original Perl を構築するときは、まず -Doptimize=-g フラグと -Uusemymalloc フラグを 指定して Configure を実行する必要があります; その後、make ターゲット "perl.third" と "test.third" を使えます。 (Perl は C<-g> フラグを使ってコンパイルする必要があります; 再 Configure が必要になる場合もあります。) =begin original The short story is that with "atom" you can instrument the Perl executable to create a new executable called F. When the instrumented executable is run, it creates a log of dubious memory traffic in file called F. See the manual pages of atom and third for more information. The most extensive Third Degree documentation is available in the Compaq "Tru64 UNIX Programmer's Guide", chapter "Debugging Programs with Third Degree". =end original 簡単に言うと、"atom" を使えば、Perl の実行可能ファイルを 調整して、F という名前の新しい 実行可能ファイルを作成することができます。 調整された実行可能ファイルが実行されると、 疑わしいメモリトラフィックのログが F という名前のファイルに 作成されます。 詳細については、atom と third のマニュアルページを参照してください。 Compaq の "Tru64 UNIX Programmer's Guide" の "Debugging Programs with Third Degree" の章に、Third Degree の最も広範な 文書があります。 =begin original The "test.third" leaves a lot of files named F in the t/ subdirectory. There is a problem with these files: Third Degree is so effective that it finds problems also in the system libraries. Therefore you should used the Porting/thirdclean script to cleanup the F<*.3log> files. =end original "test.third" は t/ サブディレクトリに F という名前の 多数のファイルを残します。 これらのファイルには問題があります: Third Degree は非常に効果的なため、 システムライブラリにも問題が見つかります。 したがって、Porting/thirdclean スクリプトを使って F<*.3log> ファイルを クリーンアップする必要があります。 =begin original There are also leaks that for given certain definition of a leak, aren't. See L for more information. =end original 定義によってはリークと言えないリークもあります; 詳細は L を参照してください。 =head2 PERL_DESTRUCT_LEVEL =begin original If you want to run any of the tests yourself manually using e.g. valgrind, or the pureperl or perl.third executables, please note that by default perl B explicitly cleanup all the memory it has allocated (such as global memory arenas) but instead lets the exit() of the whole program "take care" of such allocations, also known as "global destruction of objects". =end original 例えば valgrind や pureperl や perl.third の実行可能ファイルを使って 手動でテストを実行したい場合、 デフォルトでは perl は (グローバルメモリ領域のような)割り当てられた全てのメモリを明示的に クリーンアップ B<しません> が、代わりにプログラム全体の exit() がそのような 割り当てを"処理"します; これは"グローバルなオブジェクト破壊"としても知られています。 =begin original There is a way to tell perl to do complete cleanup: set the environment variable PERL_DESTRUCT_LEVEL to a non-zero value. The t/TEST wrapper does set this to 2, and this is what you need to do too, if you don't want to see the "global leaks": For example, for "third-degreed" Perl: =end original perl に完全なクリーンアップを行うように指示する方法があります: 環境変数 PERL_DESTRUCT_LEVEL を 0 以外の値に設定します。 t/TEST ラッパーはこれを 2 に設定しますが、"global leaks" を 見たくない場合にはこれも行う必要があります。 例えば "third-degree" Perl の場合: env PERL_DESTRUCT_LEVEL=2 ./perl.third -Ilib t/foo/bar.t =begin original (Note: the mod_perl apache module uses also this environment variable for its own purposes and extended its semantics. Refer to the mod_perl documentation for more information. Also, spawned threads do the equivalent of setting this variable to the value 1.) =end original (注: mod_perl apache モジュールも独自の目的でこの環境変数を使い、その セマンティクスを拡張しています。 詳細については、mod_perl の文書を参照してください。 また、生成されたスレッドは、この変数を値 1 に設定するのと同じことを 行います。) =begin original If, at the end of a run you get the message I, you can recompile with C<-DDEBUG_LEAKING_SCALARS>, which will cause the addresses of all those leaked SVs to be dumped along with details as to where each SV was originally allocated. This information is also displayed by Devel::Peek. Note that the extra details recorded with each SV increases memory usage, so it shouldn't be used in production environments. It also converts C from a macro into a real function, so you can use your favourite debugger to discover where those pesky SVs were allocated. =end original 実行の最後にメッセージ I が表示された場合は、 C<-DDEBUG_LEAKING_SCALARS> で再コンパイルすることができます; これにより、リークされたすべての SV のアドレスが、各 SV が最初に 割り当てられた場所の詳細とともにダンプされます。 この情報は、Devel::Peek でも表示されます。 各 SV に追加の詳細が記録されると、メモリ使用量が増加するため、本番環境では 使わないでください。 また、マクロから C を実関数に変換するため、お気に入りのデバッガを 使って、これらの SV が割り当てられた場所を検出できます。 =begin original If you see that you're leaking memory at runtime, but neither valgrind nor C<-DDEBUG_LEAKING_SCALARS> will find anything, you're probably leaking SVs that are still reachable and will be properly cleaned up during destruction of the interpreter. In such cases, using the C<-Dm> switch can point you to the source of the leak. If the executable was built with C<-DDEBUG_LEAKING_SCALARS>, C<-Dm> will output SV allocations in addition to memory allocations. Each SV allocation has a distinct serial number that will be written on creation and destruction of the SV. So if you're executing the leaking code in a loop, you need to look for SVs that are created, but never destroyed between each cycle. If such an SV is found, set a conditional breakpoint within C and make it break only when C is equal to the serial number of the leaking SV. Then you will catch the interpreter in exactly the state where the leaking SV is allocated, which is sufficient in many cases to find the source of the leak. =end original 実行時にメモリリークが発生しているが、valgrind も C<-DDEBUG_LEAKING_SCALARS> も 何も検出しない場合は、おそらく到達可能な SV がリークしており、インタプリタの 破壊時に適切にクリーンアップされている可能性があります。 このような場合、C<-Dm> スイッチを使うと、リーク元を示すことができます。 実行可能ファイルが C<-DDEBUG_LEAKING_SCALARS> でビルドされている場合、 C<-Dm> はメモリ割り当てに加えて SV 割り当てを出力します。 各 SV 割り当てには、SV の作成時と破壊時に書き込まれるシリアル番号があります。 そのため、リークしているコードをループで実行している場合は、各サイクル間に 作成されたが破壊されなかった SV を探す必要があります。 このような SV が見つかった場合は、C 内に条件付きブレークポイントを 設定し、C がリークしている SV のシリアル番号に等しい場合にのみ ブレークするようにします。 これにより、多くの場合リーク元を見つけるのに十分な、リークしている SV が 割り当てられた正確な状態でインタプリタをキャッチできます。 =begin original As C<-Dm> is using the PerlIO layer for output, it will by itself allocate quite a bunch of SVs, which are hidden to avoid recursion. You can bypass the PerlIO layer if you use the SV logging provided by C<-DPERL_MEM_LOG> instead. =end original C<-Dm> は出力に PerlIO レイヤーを使っているため、再帰を避けるために 非表示になっている大量の SV を単独で割り当てます; 代わりに C<-DPERL_MEM_LOG> が提供する SV ロギングを使う場合は、 PerlIO レイヤーをバイパスできます。 =head2 PERL_MEM_LOG =begin original If compiled with C<-DPERL_MEM_LOG>, both memory and SV allocations go through logging functions, which is handy for breakpoint setting. =end original C<-DPERL_MEM_LOG> でコンパイルした場合、メモリと SV 割り当ての両方は ロギング関数を通過します; これはブレークポイントの設定に便利です。 =begin original Unless C<-DPERL_MEM_LOG_NOIMPL> is also compiled, the logging functions read $ENV{PERL_MEM_LOG} to determine whether to log the event, and if so how: =end original C<-DPERL_MEM_LOG_NOIMPL> は付けずにコンパイルした場合、 ロギング関数は、イベントをロギングするか、およびどうやってするかを 決定するために $ENV{PERL_MEM_LOG} を読み込みます: $ENV{PERL_MEM_LOG} =~ /m/ Log all memory ops $ENV{PERL_MEM_LOG} =~ /s/ Log all SV ops $ENV{PERL_MEM_LOG} =~ /t/ include timestamp in Log $ENV{PERL_MEM_LOG} =~ /^(\d+)/ write to FD given (default is 2) =begin original Memory logging is somewhat similar to C<-Dm> but is independent of C<-DDEBUGGING>, and at a higher level; all uses of Newx(), Renew(), and Safefree() are logged with the caller's source code file and line number (and C function name, if supported by the C compiler). In contrast, C<-Dm> is directly at the point of C. SV logging is similar. =end original メモリのロギングは C<-Dm> といくらか似ていますが、C<-DDEBUGGING> とは 独立しており、より高いレベルにあります; Newx(), Renew(), Safefree() の使用は呼び出し基のソースコードファイルと 行番号 (C コンパイラが対応しているなら C 関数名も) がロギングされます。 一方、C<-Dm> は C の時点で直接です。 SV のロギングも同様です。 =begin original Since the logging doesn't use PerlIO, all SV allocations are logged and no extra SV allocations are introduced by enabling the logging. If compiled with C<-DDEBUG_LEAKING_SCALARS>, the serial number for each SV allocation is also logged. =end original ログには PerlIO が使われないため、すべての SV の割り当てがログに 記録され、ログを有効にすることによって余分な SV の割り当ては発生しません。 C<-DDEBUG_LEAKING_SCALARS> でコンパイルすると、各 SV の割り当ての シリアル番号もログに記録されます。 =head2 Profiling (プロファイリング) =begin original Depending on your platform there are various of profiling Perl. =end original プラットフォームによって、Perl をプロファイリングする方法が色々あります。 =begin original There are two commonly used techniques of profiling executables: I and I. =end original 一般的に使われる実行ファイルをプロファイリングする技術が二つあります: I<統計的タイムサンプリング>(statistical time-sampling) と I<基本ブロックカウント>(basic-block counting) です。 =begin original The first method takes periodically samples of the CPU program counter, and since the program counter can be correlated with the code generated for functions, we get a statistical view of in which functions the program is spending its time. The caveats are that very small/fast functions have lower probability of showing up in the profile, and that periodically interrupting the program (this is usually done rather frequently, in the scale of milliseconds) imposes an additional overhead that may skew the results. The first problem can be alleviated by running the code for longer (in general this is a good idea for profiling), the second problem is usually kept in guard by the profiling tools themselves. =end original 一つ目の方法では、CPU プログラムカウンタのサンプルを定期的に取得し、 プログラムカウンタは関数用に生成されたコードと照合させることができるため、 プログラムがどの関数に時間を費やしているかを統計的に把握することができます。 注意すべき点は、非常に小さい/高速な関数はプロファイルに現れる可能性が低く、 プログラムを定期的に中断すると(通常はミリ秒単位で頻繁に行われます)追加の オーバーヘッドが発生し、結果に歪みが生じる可能性があることです。 一つ目の問題は、コードをより長く実行することで軽減できます(一般的に、 これはプロファイリングに適した方法です); 二つ目の問題は、通常はプロファイリングツール自体によってガードされます。 =begin original The second method divides up the generated code into I. Basic blocks are sections of code that are entered only in the beginning and exited only at the end. For example, a conditional jump starts a basic block. Basic block profiling usually works by I the code by adding I book-keeping code to the generated code. During the execution of the code the basic block counters are then updated appropriately. The caveat is that the added extra code can skew the results: again, the profiling tools usually try to factor their own effects out of the results. =end original 2 番目の方法では、生成されたコードを I<基本ブロック> に分割します。 基本ブロックは、最初にのみ入力され、最後にのみ終了されるコードの セクションです。 たとえば、条件付きジャンプで基本ブロックが開始されます。 基本ブロックプロファイリングは通常、生成されたコードに I ブックキーピングコードを追加することにより、 コードを I<調整> して実行されます。 コードの実行中に、基本ブロックカウンタが適切に更新されます。 追加された余分なコードが結果を歪める可能性があることに注意してください: ここでも、プロファイリングツールは通常、結果から独自の影響を 考慮しようとします。 =head2 Gprof Profiling (Gprof によるプロファイリング) =begin original gprof is a profiling tool available in many Unix platforms, it uses F. =end original gprof は多くの Unix プラットフォームで利用できるプロファイルツールで、 I<統計的タイムサンプリング> を使います。 =begin original You can build a profiled version of perl called "perl.gprof" by invoking the make target "perl.gprof" (What is required is that Perl must be compiled using the C<-pg> flag, you may need to re-Configure). Running the profiled version of Perl will create an output file called F is created which contains the profiling data collected during the execution. =end original make ターゲット "perl.gprof" を呼び出すことにより、"perl.gprof" という プロファイルバージョンの perl を作成することができます(C<-pg> フラグを使って Perl をコンパイルする必要があります; 再 Configure が必要な場合もあります)。 プロファイルバージョンの Perl を実行すると、F という出力ファイルが 作成されます; このファイルには、実行中に収集されたプロファイルデータが含まれています。 =begin original The gprof tool can then display the collected data in various ways. Usually gprof understands the following options: =end original gprof ツールは、収集されたデータをさまざまな方法で表示することができます。 通常 gprof は以下のオプションを理解します: =over 4 =item -a =begin original Suppress statically defined functions from the profile. =end original 静的に定義された関数をプロファイルから抑制します。 =item -b =begin original Suppress the verbose descriptions in the profile. =end original プロファイルの詳細な説明を非表示にします。 =item -e routine =begin original Exclude the given routine and its descendants from the profile. =end original 指定されたルーチンとその子孫をプロファイルから除外します。 =item -f routine =begin original Display only the given routine and its descendants in the profile. =end original プロファイル内の指定されたルーチンとその子孫のみを表示します。 =item -s =begin original Generate a summary file called F which then may be given to subsequent gprof runs to accumulate data over several runs. =end original F という名前のサマリーファイルを生成します。 このファイルは、後続のgprof実行に渡され、複数の実行にわたってデータを 蓄積します。 =item -z =begin original Display routines that have zero usage. =end original 使用率が 0 のルーチンを表示します。 =back =begin original For more detailed explanation of the available commands and output formats, see your own local documentation of gprof. =end original 使用可能なコマンドと出力フォーマットの詳細については、gprof の ローカル文書を参照してください。 =begin original quick hint: =end original ヒント: $ sh Configure -des -Dusedevel -Doptimize='-pg' && make perl.gprof $ ./perl.gprof someprog # creates gmon.out in current directory $ gprof ./perl.gprof > out $ view out =head2 GCC gcov Profiling (GCC gcov によるプロファイリング) =begin original Starting from GCC 3.0 I is officially available for the GNU CC. =end original GCC 3.0 以降では、I<基本ブロックプロファイリング> が GNU CC 用に公式に 利用可能です。 =begin original You can build a profiled version of perl called F by invoking the make target "perl.gcov" (what is required that Perl must be compiled using gcc with the flags C<-fprofile-arcs -ftest-coverage>, you may need to re-Configure). =end original make ターゲット "perl.gcov" を呼び出すことによって、F という プロファイルバージョンの perl を構築することができます(Perl は gcc で フラグ C<-fprofile-arcs -ftest-coverage> を指定してコンパイルする 必要があります; 再 Configure が必要になる場合もあります)。 =begin original Running the profiled version of Perl will cause profile output to be generated. For each source file an accompanying ".da" file will be created. =end original プロファイルバージョンの Perl を実行すると、プロファイル出力が生成されます。 各ソースファイルに付随する ".da" ファイルが作成されます。 =begin original To display the results you use the "gcov" utility (which should be installed if you have gcc 3.0 or newer installed). F is run on source code files, like this =end original 結果を表示するには、"gcov" ユーティリティ(gcc 3.0 以降が インストールされている場合にインストールされるはずです)を使います。 F は以下のようにソースコードファイルで実行されます: gcov sv.c =begin original which will cause F to be created. The F<.gcov> files contain the source code annotated with relative frequencies of execution indicated by "#" markers. =end original F が作成されます。 F<.gcov> ファイルには、"#" マーカーで示される相対的な実行頻度で注釈が 付けられたソースコードが含まれています。 =begin original Useful options of F include C<-b> which will summarise the basic block, branch, and function call coverage, and C<-c> which instead of relative frequencies will use the actual counts. For more information on the use of F and basic block profiling with gcc, see the latest GNU CC manual, as of GCC 3.0 see =end original F の有用なオプションには、基本的なブロック、ブランチ、関数呼び出しの カバレッジを要約する C<-b> や、相対的な頻度ではなく実際のカウントを使う C<-c> などがあります。 gcc での F と基本的なブロックプロファイリングの使用に関する詳細は、 最新の GNU CC マニュアルを参照してください; GCC 3.0 では最新の GNU CC マニュアルを参照してください: http://gcc.gnu.org/onlinedocs/gcc-3.0/gcc.html =begin original and its section titled "8. gcov: a Test Coverage Program" =end original およびその "8. gcov: a Test Coverage Program" というタイトルの セクションです: http://gcc.gnu.org/onlinedocs/gcc-3.0/gcc_8.html#SEC132 =begin original quick hint: =end original ヒント: $ sh Configure -des -Doptimize='-g' -Accflags='-fprofile-arcs -ftest-coverage' \ -Aldflags='-fprofile-arcs -ftest-coverage' && make perl.gcov $ rm -f regexec.c.gcov regexec.gcda $ ./perl.gcov $ gcov regexec.c $ view regexec.c.gcov =head2 Pixie Profiling (Pixie によるプロファイリング) =begin original Pixie is a profiling tool available on IRIX and Tru64 (aka Digital UNIX aka DEC OSF/1) platforms. Pixie does its profiling using I. =end original Pixie は、IRIX および Tru64(Digital UNIX または DEC OSF/1)プラットフォームで 利用可能なプロファイリングツールです。 Pixie は I<基本ブロックカウント> を使ってプロファイリングを行います。 =begin original You can build a profiled version of perl called F by invoking the make target "perl.pixie" (what is required is that Perl must be compiled using the C<-g> flag, you may need to re-Configure). =end original make ターゲット"perl.pixie" を呼び出すことにより、F という プロファイルバージョンの perl を構築することができます(必要なのは、 C<-g> フラグを使って Perl をコンパイルすることです。 再 Configure が必要になる場合もあります)。 =begin original In Tru64 a file called F will also be silently created, this file contains the addresses of the basic blocks. Running the profiled version of Perl will create a new file called "perl.Counts" which contains the counts for the basic block for that particular program execution. =end original Tru64 では、F というファイルも静かに作成されます。 このファイルには基本ブロックのアドレスが含まれています。 プロファイルされたバージョンのPerlを実行すると、"perl.Counts" という 新しいファイルが作成されます。 このファイルには、特定のプログラムを実行するための基本ブロックの カウントが含まれています。 =begin original To display the results you use the F utility. The exact incantation depends on your operating system, "prof perl.Counts" in IRIX, and "prof -pixie -all -L. perl" in Tru64. =end original 結果を表示するには、F ユーティリティを使います。 正確な決まり文句はオペレーティングシステムによって異なります; IRIX では "prof perl.Counts"、Tru64 では "prof -pixie -all -L. perl" です。 =begin original In IRIX the following prof options are available: =end original IRIX では、次のプロファイルオプションを使えます: =over 4 =item -h =begin original Reports the most heavily used lines in descending order of use. Useful for finding the hotspot lines. =end original 最も頻繁に使われている行を降順でレポートします。 ホットスポットの行を見つけるのに便利です。 =item -l =begin original Groups lines by procedure, with procedures sorted in descending order of use. Within a procedure, lines are listed in source order. Useful for finding the hotspots of procedures. =end original プロシージャごとに明細をグループ化します; プロシージャは使用の降順にソートされます。 プロシージャ内では、明細はソース順にリストされます。 プロシージャのホットスポットを検索する場合に便利です。 =back =begin original In Tru64 the following options are available: =end original Tru64 では、次のオプションを使えます: =over 4 =item -p[rocedures] =begin original Procedures sorted in descending order by the number of cycles executed in each procedure. Useful for finding the hotspot procedures. (This is the default option.) =end original 各プロシージャで実行されたサイクル数の降順にソートされたプロシージャ。 ホットスポットプロシージャを検索するのに便利です。(これはデフォルトの オプションです。) =item -h[eavy] =begin original Lines sorted in descending order by the number of cycles executed in each line. Useful for finding the hotspot lines. =end original 各行で実行されたサイクル数の降順にソートされた行。 ホットスポットの行を見つけるのに便利です。 =item -i[nvocations] =begin original The called procedures are sorted in descending order by number of calls made to the procedures. Useful for finding the most used procedures. =end original 呼び出されたプロシージャは、プロシージャに対して行われたコール数の降順で ソートされます。 最も使われているプロシージャを検索する場合に便利です。 =item -l[ines] =begin original Grouped by procedure, sorted by cycles executed per procedure. Useful for finding the hotspots of procedures. =end original プロシージャ別にグループ化され、プロシージャごとに実行されるサイクル別に ソートされます。 プロシージャのホットスポットを見つけるのに便利です。 =item -testcoverage =begin original The compiler emitted code for these lines, but the code was unexecuted. =end original コンパイラはこれらの行のコードを出力しましたが、コードは実行されませんでした。 =item -z[ero] =begin original Unexecuted procedures. =end original 実行されていないプロシージャ。 =back =begin original For further information, see your system's manual pages for pixie and prof. =end original 詳細については、システムのマニュアルページの pixie と prof を 参照してください。 =head2 Miscellaneous tricks (様々な小技) =over 4 =item * =begin original Those debugging perl with the DDD frontend over gdb may find the following useful: =end original gdb 上で DDD フロントエンドを使って perl をデバッグする場合は、 次のような方法が便利です: =begin original You can extend the data conversion shortcuts menu, so for example you can display an SV's IV value with one click, without doing any typing. To do that simply edit ~/.ddd/init file and add after: =end original データ変換ショートカットメニューを拡張できます; たとえば、SV の IV 値を 1 回クリックするだけで表示できます; キーを押す必要はありません。 これを行うには、~/.ddd/init ファイルを編集し、次の部分の後に追加します: ! Display shortcuts. Ddd*gdbDisplayShortcuts: \ /t () // Convert to Bin\n\ /d () // Convert to Dec\n\ /x () // Convert to Hex\n\ /o () // Convert to Oct(\n\ =begin original the following two lines: =end original 次の 2 行です: ((XPV*) (())->sv_any )->xpv_pv // 2pvx\n\ ((XPVIV*) (())->sv_any )->xiv_iv // 2ivx =begin original so now you can do ivx and pvx lookups or you can plug there the sv_peek "conversion": =end original ivx と pvx のルックアップを行うか、sv_peek "conversion" を接続します。 Perl_sv_peek(my_perl, (SV*)()) // sv_peek =begin original (The my_perl is for threaded builds.) Just remember that every line, but the last one, should end with \n\ =end original (my_perl はスレッド化ビルド用です)。 最後の行以外のすべての行は \n\ で終わることを覚えておいてください。 =begin original Alternatively edit the init file interactively via: 3rd mouse button -> New Display -> Edit Menu =end original または、3 番目のマウスボタン-> New Display - Edit Menu を 使って、対話的に init ファイルを編集します。 =begin original Note: you can define up to 20 conversion shortcuts in the gdb section. =end original 注: gdb セクションでは、最大 20 の変換ショートカットを定義できます。 =item * =begin original If you see in a debugger a memory area mysteriously full of 0xABABABAB or 0xEFEFEFEF, you may be seeing the effect of the Poison() macros, see L. =end original デバッガ内のメモリ領域が 0xABABABAB または 0xEFEFEFEF で神秘的に いっぱいになっている場合は、Poison() マクロの効果が表示されている 可能性があります。 L を参照してください。 =item * =begin original Under ithreads the optree is read only. If you want to enforce this, to check for write accesses from buggy code, compile with C<-DPL_OP_SLAB_ALLOC> to enable the OP slab allocator and C<-DPERL_DEBUG_READONLY_OPS> to enable code that allocates op memory via C, and sets it read-only at run time. Any write access to an op results in a C and abort. =end original ithreads では、op 木は読み取り専用です。 バグのあるコードからの書き込みアクセスを チェックするためにこれを強制したい場合は、 C<-DPL_OP_SLAB_ALLOC> でコンパイルして OP スラブアロケーターを有効にし、C<-DPERL_DEBUG_READONLY_OPS>で コンパイルして C 経由で op メモリを割り当てるコードを有効にし、 実行時に読み取り専用に設定します。 op への書き込みアクセスは C で中断されます。 =begin original This code is intended for development only, and may not be portable even to all Unix variants. Also, it is an 80% solution, in that it isn't able to make all ops read only. Specifically it =end original このコードは開発のみを目的としており、すべての Unix バリエーションに 移植できるわけではありません。 また、すべての op を読み取り専用にすることができないという点で、80% の ソリューションです。 具体的には: =over =item 1 =begin original Only sets read-only on all slabs of ops at C time, hence ops allocated later via C or C will be re-write =end original C 時に op のすべてのスラブに読み取り専用のみを設定します。 したがって、後で C または C によって割り当てられた op は 再書き込みされます。 =item 2 =begin original Turns an entire slab of ops read-write if the refcount of any op in the slab needs to be decreased. =end original スラブ内の任意の op の refcount を減らす必要がある場合は、op のスラブ全体を 読み書き可能にします。 =item 3 =begin original Turns an entire slab of ops read-write if any op from the slab is freed. =end original スラブから任意の op が解放された場合、op のスラブ全体を 読み書き可能にします。 =back =begin original It's not possible to turn the slabs to read-only after an action requiring read-write access, as either can happen during op tree building time, so there may still be legitimate write access. =end original 読み取り/書き込みアクセスを必要とするアクションの後で、スラブを 読み取り専用にすることはできません; これは、op 木の構築時に発生する可能性があるため、正当な 書き込みアクセスが存在する可能性があります。 =begin original However, as an 80% solution it is still effective, as currently it catches a write access during the generation of F, which means that we can't yet build F with this enabled. =end original しかし、80% のソリューションとしてはまだ有効です。 現在のところ、F の生成中に書き込みアクセスをキャッチしているため、 これを有効にして F を構築することはできません。 =back =head1 CONCLUSION (結び) =begin original We've had a brief look around the Perl source, how to maintain quality of the source code, an overview of the stages F goes through when it's running your code, how to use debuggers to poke at the Perl guts, and finally how to analyse the execution of Perl. We took a very simple problem and demonstrated how to solve it fully - with documentation, regression tests, and finally a patch for submission to p5p. Finally, we talked about how to use external tools to debug and test Perl. =end original Perl ソースの概要、ソースコードの品質を維持する方法、F がコードを 実行する段階の概要、デバッガを使って Perl の本質を探る方法、そして最後に Perl の実行を分析する方法について簡単に説明しました。 非常に単純な問題を取り上げ、文書、回帰テスト、そして最後に p5p に 提出するためのパッチを使って、問題を完全に解決する方法を説明しました。 最後に、外部ツールを使って Perl をデバッグおよびテストする方法について 説明しました。 =begin original I'd now suggest you read over those references again, and then, as soon as possible, get your hands dirty. The best way to learn is by doing, so: =end original これらのリファレンスをもう一度読み通して、それから、できるだけ早く、 手を汚すことを提案します。 学ぶための最良の方法はやってみることです; 従って: =over 3 =item * =begin original Subscribe to perl5-porters, follow the patches and try and understand them; don't be afraid to ask if there's a portion you're not clear on - who knows, you may unearth a bug in the patch... =end original perl5-porters を購読して、パッチを追いかけ、試してみて理解します; はっきりしない部分を訊ねるのを恐れないでください - あなたがパッチのバグを 掘り出すかも知れないことを知っています… =item * =begin original Keep up to date with the bleeding edge Perl distributions and get familiar with the changes. Try and get an idea of what areas people are working on and the changes they're making. =end original Perl 配布の最新を追いかけ続けて、変更に慣れ親しみます。 どの分野で人々が作業していて変更が行われているかを理解しようとします。 =item * =begin original Do read the README associated with your operating system, e.g. README.aix on the IBM AIX OS. Don't hesitate to supply patches to that README if you find anything missing or changed over a new OS release. =end original オペレーティングシステムに関連づけられた README (例えば IBM AIX OS なら README.aix) を読みます。 新しい OS のリリースで抜けていたり変更されていることに気付いたら、 その README へのパッチを提供することを遠慮しないでください。 =item * =begin original Find an area of Perl that seems interesting to you, and see if you can work out how it works. Scan through the source, and step over it in the debugger. Play, poke, investigate, fiddle! You'll probably get to understand not just your chosen area but a much wider range of F's activity as well, and probably sooner than you'd think. =end original 自分にとって興味深いと思われる Perl の分野を見つけて、作業をすると どのように動作するかを見ます。 ソースをスキャンして、デバッガでステップ実行します。 遊んでつついて調べていじります! おそらく、選んだ分野だけではなく、F のもっと広い範囲の動作も 理解する必要があって、それはおそらくあなたが考えているより早いでしょう。 =back =over 3 =item I (I<道はつづくよ、先へ先へと、戸口より出て、遠くへつづく。>) =back =begin original If you can do these things, you've started on the long road to Perl porting. Thanks for wanting to help make Perl better - and happy hacking! =end original これらのことができれば、Perl porting への長い道の開始です。 Perl をよりよくする助けをしようとしてくれてありがとう - そして happy hacking! =head2 Metaphoric Quotations (比喩的な引用) =begin original If you recognized the quote about the Road above, you're in luck. =end original 上述の道に関する引用に気付いたなら、運があります。 =begin original Most software projects begin each file with a literal description of each file's purpose. Perl instead begins each with a literary allusion to that file's purpose. =end original ほとんどのソフトウェアプロジェクトでは、それぞれのファイルは、ファイルの 目的の文字通りの説明で始まります。 Perl はそうではなく、ファイルの目的の文学的な言及で始まります。 =begin original Like chapters in many books, all top-level Perl source files (along with a few others here and there) begin with an epigramic inscription that alludes, indirectly and metaphorically, to the material you're about to read. =end original 多くの本の章のように、トップレベル (およびあちこちにあるいくつかの) Perl ソースファイルは、今から読もうとしているものへの暗示的、間接的、 隠喩的な警句的碑文で始まります。 =begin original Quotations are taken from writings of J.R.R Tolkien pertaining to his Legendarium, almost always from I. Chapters and page numbers are given using the following editions: =end original 引用は J.R.R Tolkien の著作とそれに付随する世界から取られます; ほとんど常に I (指輪物語) からです。 章と頁番号は以下の版から取られています: =over 4 =item * =begin original I, by J.R.R. Tolkien. The hardcover, 70th-anniversary edition of 2007 was used, published in the UK by Harper Collins Publishers and in the US by the Houghton Mifflin Company. =end original J.R.R. Tolkien による I (ホビットの冒険)。 イギリスでは Harper Collins Publishers から、アメリカでは the Houghton Mifflin Company から出版された、2007 年の 70 周年記念ハードカバー版が 使われています。 =item * =begin original I, by J.R.R. Tolkien. The hardcover, 50th-anniversary edition of 2004 was used, published in the UK by Harper Collins Publishers and in the US by the Houghton Mifflin Company. =end original J.R.R. Tolkien による I (指輪物語)。 イギリスでは Harper Collins Publishers から、アメリカでは the Houghton Mifflin Company から出版された、2004 年の 50 周年記念ハードカバー版が 使われています。 =item * =begin original I, by J.R.R. Tolkien and published posthumously by his son and literary executor, C.J.R. Tolkien, being the 3rd of the 12 volumes in Christopher's mammoth I. Page numbers derive from the hardcover edition, first published in 1983 by George Allen & Unwin; no page numbers changed for the special 3-volume omnibus edition of 2002 or the various trade-paper editions, all again now by Harper Collins or Houghton Mifflin. =end original J.R.R. Tolkien による I; 死後、息子であり 遺著管理者である C.J.R. Tolkien によって出版された 12 巻からなる巨大な I の第 3 巻。 頁番号は George Allen & Unwin から 1983 年に出版されたハードカバー版に 依っています; Harper Collins や Houghton Mifflin による、2002 年の特別 3 巻 オムニバス版や様々な trade-paper 版でも頁番号は変わっていません。 =back =begin original Other JRRT books fair game for quotes would thus include I, I, I, and I, all but the first posthumously assembled by CJRT. But I itself is perfectly fine and probably best to quote from, provided you can find a suitable quote there. =end original その他の JRRT の本である I (トム・ボンバディルの冒険)、I(シルマリルの物語)、 I(終わらざりし物語)、 I も引用の元となります (最初のもの以外は 死後 CJRT によって編纂されたものです)。 しかし、適切な引用が見つけられるなら、I は引用元として 完全によく、おそらく最良のものです。 =begin original So if you were to supply a new, complete, top-level source file to add to Perl, you should conform to this peculiar practice by yourself selecting an appropriate quotation from Tolkien, retaining the original spelling and punctuation and using the same format the rest of the quotes are in. Indirect and oblique is just fine; remember, it's a metaphor, so being meta is, after all, what it's for. =end original それで、Perl に追加するための新しくて完全なトップレベルソースファイルを 提供しようとしているなら、Tolkien から適切な引用を自分で選択して、 元の綴りと句読点を残して他の引用と同じ形式を使うという、特有の慣例に 従うべきです。 間接的で遠回しでもかまいません; これはメタファーであり、メタであると いうことは、結局、ためにするものであるということを忘れないでください。 =head1 AUTHOR =begin original This document was written by Nathan Torkington, and is maintained by the perl5-porters mailing list. =end original この文書は Nathan Torkington によって書かれ、perl5-porters メーリングリストで 管理されています。 =head1 SEE ALSO L =begin meta Translate: SHIRAKATA Kentaro Status: completed =end meta