perlfaq3 - プログラミングツール
FAQ のこのセクションでは、プログラマーツールやプログラミングサポートに 関する質問に回答しています。
CPAN (perlfaq2 を参照して下さい)はもう見ましたか? あなたの問題を解決してくれるような モジュールを誰かがすでに作っているのを見つけられるかもしれません。 適切なマニュアルページは見ましたか? 簡単なインデックスを挙げておきます:
基礎 perldata, perlvar, perlsyn, perlop, perlsub
実行 perlrun, perldebug
関数 perlfunc
オブジェクト perlref, perlmod, perlobj, perltie
データ構造 perlref, perllol, perldsc
モジュール perlmod, perlmodlib, perlsub
正規表現 perlre, perlfunc, perlop, perllocale
perl5への移行 perltrap, perl
Cとのリンク perlxstut, perlxs, perlcall, perlguts, perlembed
その他 http://www.cpan.org/misc/olddoc/FMTEYEWTK.tgz
(man-page ではありませんが有用な、Perl のテクニックに
関するコラム集です)
無加工の Perl のマニュアルページセットの目次の一覧が perltoc にあります。
典型的なやり方は、perldebug(1)
マニュアルページにあるような Perl デバッガを以下の例のように「空の」プログラムに対して使うことです:
perl -de 42
これで、正しい Perl コードをタイプするだけで即座にそれが評価されます。 同様に、シンボルテーブルの検査やスタックのバックトレースを得ること、 変数の値の確認、ブレークポイントの設定、そしてシンボリックデバッガで 行える典型的な操作が可能です。
psh
(Perl sh) は現在バージョン 1.8 です。 Perl Shell は Unix シェルの対話性と Perl の力を融合したものです。 目標は通常のシェルのような機能および、フロー制御やその他のことに Perl の文法と機能を使う完全な機能を持ったシェルです。 psh
は http://www.focusresearch.com/gregor/psh/ で入手できます。
Zoidberg
は似たようなプロジェクトで perl で書かれたシェルを提供します。 これは perl で設定され、perl で動作します。 これはログインシェルと開発環境を意図しています。 http://pardus-larus.student.utwente.nl/~pardus/projects/zoidberg/ またはお近くの CPAN ミラーにあります。
(Perl と一緒に配布されている) Shell.pm
モジュールは、Perl が Perl 言語の 一部ではないコマンドをシェルコマンドのように試してみるようにさせます。 ソース配布と一緒にある perlsh
は単純で、面白みに欠けるものかも しれませんが、あなたの要求には十分かもしれません。
コマンドラインからは、-l
オプション付きの cpan
コマンドが使えます:
$ cpan -l
また、cpan
の -a
オプションを使うことで、CPAN.pm
が理解して、 全てのモジュールを再インストールするために使える autobundle ファイルも 作れます。
$ cpan -a
Perl プログラム内では、 ExtUtils::Installed
モジュールを使うことで全てのインストールされた ディストリビューションを知ることが出来ますが、この魔法を使うには 少し時間がかかります。 Perl と共に入る標準ライブラリは単に "Perl" として表示されます (しかしこれらのリストは Module::CoreList
で得ることが出来ます)。
use ExtUtils::Installed;
my $inst = ExtUtils::Installed->new();
my @modules = $inst->modules();
全ての Perl モジュールファイル名の一覧を知りたいなら、 File::Find::Rule
が利用できます:
use File::Find::Rule;
my @files = File::Find::Rule->
extras({follow => 1})->
file()->
name( '*.pm' )->
in( @INC )
;
このモジュールがない場合、標準ライブラリの一部である File::Find
を使って同じことが出来ます:
use File::Find;
my @files;
find(
{
wanted => sub {
push @files, $File::Find::fullname
if -f $File::Find::fullname && /\.pm$/
},
follow => 1,
follow_skip => 2,
},
@INC
);
print join "\n", @files;
単にあるモジュールが使えるかどうかを知りたいだけなら、 ドキュメントをチェックするという方法があります。 もしそのモジュールに関するドキュメントが読めるなら、 そのモジュールはきっとインストールされています。 ドキュメントが読めない場合、(まれに)モジュールにドキュメントが ないという可能性もあります:
$ perldoc Module::Name
一行野郎でモジュールを読み込めるか試すという手もあります:
$ perl -MModule::Name -e1
(brian d foy によって寄贈されました)
他の事をする前に、あなたのコードの問題を Perl に調べさせることで あなたへの助けとすることが出来ます。 警告と厳密性をオンにすることによって、多くの問題を大事になる前に 阻止できます。 これらに関する詳細は strict と warnings にあります。
#!/usr/bin/perl
use strict;
use warnings;
その他に、もっとも単純なデバッガは print
関数です。 プログラム実行中に値を見るために使います:
print STDERR "The value is [$value]\n";
Data::Dumper
モジュールは Perl のデータ構造をきれいに表示します:
use Data::Dumper qw( Dumper );
print STDERR "The hash is " . Dumper( \%hash ) . "\n";
Perl には対話的デバッガが同梱されていて、-d
スイッチを付けることで 起動できます。 perldebug で完全に説明されています。
もし GUI がほしくて、Tk
がある場合、ptkdb
が使えます。 これは CPAN にあり、自由に使えます。
もっと洗練されていて制御可能なものが必要なら、Leon Brocard の Devel::ebug
(-D
オプションを使って -Debug
として呼び出せます)を使うと、 なんでもあなたが自分で書いたものを使って(それほどの苦痛なしに)プログラム上の フックを作れます。
Affrus (Mac OS X), Activestate Komodo (Windows と Mac OS X), EPIC (ほとんどのプラットフォーム) といった商用デバッガも使えます。
(brian d foy によって寄贈され、Fri Jul 25 12:22:26 PDT 2008 に 更新されました)
Devel
名前空間には Perl プログラムをプロファイルするために使える いくつかのモジュールがあります。 Devel::DProf
モジュールは Perl と共に配布されていて、 -d
オプションで起動できます:
perl -d:DProf program.pl
DProf
の元でプログラムを動かした後、プロファイルデータとして tmon.out ファイルが得られます。 このデータを見るためには、Devel::DProf
と共に配布されている dprofpp
プログラムで人間が読める形のレポートに変換します。
dprofpp
また、dprofpp
に -p
オプションを付けることで、プロファイリングと レポートを一度に行うことも出来ます:
dprofpp -p program.pl
Devel::NYTProf
(New York Times Profiler) は文とサブルーチンの 両方のプロファイリングを行います。 これは CPAN から入手可能で、やはり -d
オプションで起動できます:
perl -d:NYTProf some_perl.pl
DProf
と同様、レポートに変換できるプロファイル情報のデータベースを 作成します。 nytprofhtml
コマンドで、データを Devel::Cover
レポートと似たような HTML レポートに変換します:
nytprofhtml
CPAN には同じ形で起動できるその他のプロファイラもいくつかあります。 また、コード片を計測、比較するために Benchmark
を使うことにも 興味があるかもしれません。
プロファイルに関するさらなることについては Programming Perl の 20 章か Mastering Perl の 5 章を読んでください。
perldebguts には、特別な種類のプロファイラが必要な場合に カスタムデバッガを作る方法が書かれています。 brian d foy は The Perl Journal の "Creating a Perl Debugger", http://www.ddj.com/184404522 と "Profiling in Perl" http://www.ddj.com/184404580 で処理を記述しています。
Perl.com にはプロファイリングに関する二つの興味深い記事があります: Simon Cozens による "Profiling Perl" http://www.perl.com/lpt/a/850 と Frank Wiles による "Debugging and Profiling mod_perl Applications" http://www.perl.com/pub/a/2006/02/09/debug_mod_perl.html です。
Randal L. Schwartz はプロファイリングについて Unix Review の "Speeding up Your Perl Programs" http://www.stonehenge.com/merlyn/UnixReview/col49.html と、 Linux Magazine の "Profiling in Template Toolkit via Overriding" http://www.stonehenge.com/merlyn/LinuxMag/col75.html で書いています。
B::Xref
モジュールが Perl プログラムに対する クロスリファレンスの報告を生成するのに使えます。
perl -MO=Xref[,OPTIONS] scriptname.plx
Perltidy
は Perl スクリプトを perlstyle のルールに従って 読みやすくしようとする Perl スクリプトです。 Perl スクリプトを書いたとき、あるいは多くの時間を Perl スクリプトを 読むのに費やすとき、多分これが有用です。 http://perltidy.sourceforge.net で入手できます。
もちろん、あなたが perlstyle に従っているのであれば、 リフォーマットする必要はないでしょう。 自分のプログラムの書式を統一しておく習慣はバグ対策になります。 あなたの使っているエディターはソースのフォーマッティングを 助けてくれるかもしれません。 emacs の perl モードやより新しい cperl モードは、コードの ほとんど(が、全部ではありません)に対して驚くほどたくさんの手助けを 提供してくれるでしょうし、そしてそれよりも非力なプログラム可能な エディターでさえも明らかな手助けを提供してくれるかもしれません。 Tom Christiansen とその他の多くの vi 使いは vi (とそのクローン)で 以下のような設定を使っています:
set ai sw=4
map! ^O {^M}^[O^T
これをあなたの .exrc というファイル(キャレット文字はコントロール文字で 置き換えます)に書き込めば OK です。 挿入モードでは ^T はインデントを行い、^D はアンインデントを、 ^Oは blockdent をします。 コメント付きの、より完全な例は http://www.perl.com/CPAN-local/authors/id/TOMC/scripts/toms.exrc.gz にあります。
http://www-inf.enst.fr/%7Edemaille/a2ps/black+white.ps.gz にある a2ps は 奇麗なドキュメントを出力するということに関して多くのことを行います。
(brian d foy によって寄贈されました)
ctags はソースコード内のものを素早く探すためにインデックスを使い、多くの 有名なエディタは Perl を含むいくつかの言語に対して ctags に対応しています。
Exuberant ctags は Perl に対応しています: http://ctags.sourceforge.net/
pltags も試してみてください: http://www.mscha.com/pltags.zip
Perl プログラムは単なるテキストなので、どんなエディタでも作成できます。
あなたが Unix を使っているなら、あなたはすでに統合開発環境を 手にしています--それは Unix 自身です。 Unix の哲学は、一つのことをうまくこなせる小さなツールを複数 組み合わせることです。 これは大工の道具箱に似ています。
統合開発環境がほしいなら、以下をチェックしてください (アルファベット順であって、有用な順ではありません):
http://e-p-i-c.sf.net/
The Eclipse Perl Integration Project は Perl の編集/デバッグを Eclipse に 統合します。
http://www.enginsite.com/
EngInSite の Perl Editor Perl スクリプトを作成・テスト・デバッグするための 完全な統合開発環境(IDE)です; ツールは Windows 9x/NT/2000/XP 移行で 動作します。
http://www.ActiveState.com/Products/Komodo/
ActiveState のクロスプラットフォーム(2004 年 10 月現在 Windows, Linux, Solaris) 多言語 IDE は、 正規表現デバッガ、リモートデバッグを含む Perl サポートがあります。
http://notepad-plus.sourceforge.net/
http://open-perl-ide.sourceforge.net/
Open Perl IDE は Windows 95/98/NT/2000 で動作する ActiveState の ActivePerl で Perl スクリプトを書いたりデバッグしたりするための 統合開発環境です。
http://www.optiperl.com/
OptiPerl は擬似 CGI 環境を持つ Windows 用 IDE で、 デバッガと文法によって色付けされるエディタを含みます。
http://padre.perlide.org/
Padre は、ネイティブな見た目を提供するために wxWidgets を使って Perl で 書かれた Perl のためのクロスプラットフォーム IDE です。
http://www.solutionsoft.com/perl.htm
PerlBuilder は Windows 用統合開発環境で、Perl の開発にも対応しています。
http://helpconsulting.net/visiperl/
Help Consulting 製で、Windows 用です。
http://www.activestate.com/Products/Visual_Perl/
Visual Perl は ActiveState 製で、Visual Studio.NET へのプラグインです。
http://www.zeusedit.com/lookmain.html
Zeus for Window は Perl にも対応した、もう一つの Win32 複数言語 エディタ/IDEです。
エディタ使いへ: あなたが Unix を使っているなら、おそらく vi か vi クローンがすでにあるはずで、emacs もあるかもしれません。 それで、あなたは何もダウンロードする必要はないかもしれません。 あらゆるバージョンの emacs で使える cperl-mode (M-x cperl-mode) は おそらくエディタでの Perl 編集モードの中で最高のものでしょう。
Windows を使っているのなら、NotePad や WordPad といった プレーンテキストを扱えるエディタを使うことが出来ます。 Microsoft Word や WordPerfect といったワードプロセッサは 一般的には使えません。なぜなら色々な「裏方の」情報を追加するからです。 ただし、"Text Only" としてファイルをセーブできるものもあります。 また、Textpad ( http://www.textpad.com/ ) や UltraEdit ( http://www.ultraedit.com/ ) といったプログラミングに特化した テキストエディタをダウンロードすることもできます。
MacOS を使っているなら、同様の考え方が適用されます。 (Classic 環境用の)MacPerl にはシンプルなエディタが付いています。 有名な外部エディタとしては BBEdit ( http://www.bbedit.com/ ) や Alpha ( http://www.his.com/~jguyer/Alpha/Alpha8.html ) があります。 MacOS X ユーザーは Unix エディタも使えます。
http://www.gnu.org/software/emacs/windows/ntemacs.html
http://www.microemacs.de/
http://www.xemacs.org/Download/index.html
http://space.mit.edu/~davis/jed/
あるいは以下のような vi クローンもあります:
ftp://ftp.cs.pdx.edu/pub/elvis/ http://www.fh-wedel.de/elvis/
http://dickey.his.com/vile/vile.html
http://www.vim.org/
一般的な、Windows やその他の vi 愛好者のために:
http://www.thomer.com/thomer/vi/vi.html
nvi (http://www.bostic.com/vi/ , CPAN の src/misc/ にもあります)は vi クローンの一つで、残念ながら Windows では動作しませんが、 Unix プラットフォームを使っているなら試してみるべきです。 第一の理由としては、厳密には vi クローンではないものの、 実際は vi、あるいは vi の子孫であるからです。 第二の理由としては、Perl を内蔵していて、Perl をスクリプト言語として 使えるからです。 しかし、nvi はこれらの機能をもつ唯一のものではありません。 少なくとも vim と vile も内蔵 Perl を提供しています。
以下は Perl をサポートしている Win32 多言語エディタ/IDE です。
http://www.borland.com/codewright/
http://www.MultiEdit.com/
http://www.slickedit.com/
http://www.contexteditor.org/
CPAN で Tk モジュールと共に配布されている、Perl で書かれた toyedit Text ウィジェットベースのエディタがあります。 ptkdb( http://ptkdb.sourceforge.net/ ) は 開発環境として振舞う Perl/Tk ベースのデバッガです。 Perl Composer ( http://perlcomposer.sourceforge.net/vperl.html )は Perl/Tk GUI を使った IDE です。
エディタ/統合開発環境に加えて、Win32 環境でのより強力な シェル環境に興味があるかもしれません。 選択肢としては以下のものがあります:
Cygwin パッケージ ( http://sources.redhat.com/cygwin/ ) から。
MKS ツールキット ( http://www.mkssoftware.com/ )か、 U/WIN 環境 ( http://www.research.att.com/sw/tools/uwin/ ) の Bourne shell から。
ftp://ftp.astron.com/pub/tcsh/ ; http://www.primate.wisc.edu/software/csh-tcsh-book/ も参照してください。
http://www.zsh.org/
MKS とU/WIN は商用(U/WIN は教育・研究目的には無料)で、 Cygwin は GNU General Public License で配布されています (しかしこれは Perl の使用には関係ないはずです)。 Cygwin, MSK, U/WIN は全て(シェルに加えて)広範囲な標準 Unix ツールキットを含んでいます。
Unix と Windows の間でテキストファイルを FTP で転送する場合、 改行コードを適切に変更するために ASCII モードにしてください。
Mac OS では MacPerl Application は基本的な IDE のように振舞う シンプルな 32k テキストエディタがついています。 MacPerl Application と対照的に、MPW Perl tool は MPW Shell 自身を (32k の制限なしに)エディタとして使えます。
は、完全なデバッガサポート付きの完全な Perl 開発環境です ( http://www.latenightsw.com )。
これはエディタで、Tcl で書かれており、拡張可能です。 それでもいくつかの有名なマークアップ言語とプログラミング言語 ( Perl と HTML を含みます)への対応を内蔵しています ( http://www.his.com/~jguyer/Alpha/Alpha8.html )。
これは Mac OS で動作するテキストエディタで、 Perl 用のモードがあります( http://web.barebones.com/ )。
Tom Christiansen の vi コンフィグレーションファイルの完全なものは vi エミュレータの標準ベンチマークファイルである http://www.cpan.org/authors/Tom_Christiansen/scripts/toms.exrc.gz を参照してください。 これは Berkeley の外にあるviのカレントバージョンである nvi で 最もうまく実行されます。 nvi は組み込みの Perl インタプリタをつけてビルドすることもできます。 http://www.cpan.org/src/misc/ を参照してください。
Emacs のバージョン 19 パッチレベル 22 から、perl-mode.el と組み込みの Perl デバッガをサポートしています。 これらは標準の Emacs19 配布セットと一緒にあるはずです。
emacs の perl-mode は "main'foo"
(シングルクォート)スタイルを扱うもので、 インデントやハイライトをおかしくしてしまうことに注意してください。 いずれにしろ、"main::foo"
を使うべきでしょう。
CPerlMode については、http://www.emacswiki.org/cgi-bin/wiki/CPerlMode を 参照してください。
CPAN にある Curses モジュールは、curses ライブラリに対する動的に ロード可能なオブジェクトモジュールインターフェースを提供します。 ちょっとしたデモが http://www.cpan.org/authors/Tom_Christiansen/scripts/rep.gz にあります。 このプログラムはコマンドを繰り返し、必要に応じて 画面を更新し、top と同じく rep ps axu をレンダリングします。
(Ben Morrow によって寄贈されました)
Perl で GUI を書くための多くのモジュールがあります。 ほとんどの GUI ツールキットには perl インターフェースがあります: 以下に不完全なリストを示します。
これは Unix と Windows で動作し、現在のバージョンは Windows でも以前のように 悪くはないです。 しかし、GUI 要素には完全に正しい「感じ」ではないものもあります。 インターフェースはとても自然で「perl っぽい」もので、単純な GUI が ほしいだけの小さいスクリプトで簡単に使えます。 これはしばらくの間更新されていません。
これは クロスプラットフォーム wxWidgets ツールキット ( http://www.wxwidgets.org ) の Perl バインディングです。 これは ネイティブなウィジェット(Unix では Gtk) を使って、 Unix, Win32, Mac OS X で動作します。 インターフェースは C++ インターフェースに近いですが、 ドキュメントはライブラリを知らない人にとっては少々手薄なので、 たいていは単に C++ ドキュメントを参照することになるでしょう。
Gtk ツールキット ( http://www.gtk.org ) の Perl バインディングがあります。 バージョン 1 と 2 でインターフェースが大きく変わったので、個別の Perl モジュールになっています。 これは Unix, Win32, Mac OS X で動作し(現在のところ Mac OS X では X サーバーが必要ですが、「ネイティブ」ポートも進行中です)、ウィジェットは どのプラットフォームでも同じような見た目になります(つまり、ネイティブの ウィジェットとは一致しません)。 Wx と同様、Perl バインディングは C API に似ていて、これを理解するためには C のドキュメントを読む必要があります。
これは Perl から Win32 GUI ウィジェットのほとんどへのアクセスを提供します。 明らかに、これは Win32 でのみ動作し、ネイティブなウィジェットを使います。 Perl のインターフェースは C のインターフェースに本当に従ってはいません: これはより Perl っぽく、ドキュメントもかなりよく出来ています。 より高度な機能を使うためには C Win32 API に親しんでいるか、MSDN を 参照する必要があります。
CamelBones ( http://camelbones.sourceforge.net ) は Mac OS X の Cocoa GUI への Perl のインターフェースで、Mac OS X でのネイティブな GUI の生成に使えます。 これは CPAN.pm がどのようにインストールすればよいか知らないフレームワークを 必要とするので CPAN にはありませんが、標準 OSX パッケージインストーラ経由で インストールします。 再び、Perl API はそれがラッピングしている ObjC API ととても近いので、 ドキュメントは単にお互いをどう変換すればいいかについて書いています。
TrollTech の Qt toolkit への Perl インターフェースはありますが、 保守されていないようです。
Sx は X に同梱されている Athena ウィジェットセットへのインターフェースですが、 やはり最近ではほとんど使われていないようです。
その最善の方法とは、よりよいアルゴリズムを使うということです。 ラクダ本の第八章にはあなたが感心をよせるかもしれない幾つかの効率的な tips があります。 Jon Bentleyの著作 "Programming Pearls" (ミススペルではありません!) (邦訳「珠玉のプログラミング」)にも最適化に関するいくつかの Tips があります。 ベンチマークとプロファイルによって、 あなたのプログラムのどこに手を入れて最適化するのが正しいのかを はっきりさせ、ちまちまと高速化を行うのではなくより良いアルゴリズムを 探す手掛かりになります。 そして、どうしようもなくなったときには いつ新しいハードウェアを買うかということを知る手掛かりともなります。 まだ読んでいないなら、前述した "How do I profile my Perl programs?" という 質問の答えも読みたいと思うでしょう。
別のアプローチには、時々使う Perl コードをオートローディングすると いうものがあります。 このために標準配布キットにある AutoSplit モジュールと AutoLoader モジュールを参照してください。 あるいは、ボトルネックとなっているところを特定し、その部分を C で書くことを考えるかもしれません。 ちょうど C で書かれたプログラムのボトルネックをアセンブラで 書くのと同じことです。 C で書き直すという意味では、クリティカルセクションを持ったモジュールを C で書き直すというのも同様です(例えば、CPAN にある PDL モジュールがそうです)。
もしあなたが今、perl の実行ファイルと共有ライブラリ libc.so
を リンクしているのであれば、スタティックに libc.a とリンクして perl を 再ビルドすることによって、しばしば 10-25% 性能を 向上させることが可能です。 これは perl の実行ファイルを大きなものにしてしまいますが、 あなたの Perl プログラム(とプログラマー)はスタティックリンクされたことを 感謝するでしょう。 より詳しい情報は、ソース配布にある INSTALL というファイルを 参照してください。
undump プログラムは、コンパイル済みの形式でディスクに格納することで Perlプログラムを高速化するのに古くは使われていました。 これはほんの一部のアーキテクチャーでのみ働くものであって、 最早価値ある選択肢ではなく、かつ、よい解決策ではありません。
時間と空間とを天秤に掛けたとき、Perl はほとんど常にメモリに関する 問題を放棄します。 Perl におけるスカラーは C の文字列よりもメモリを消費し、 配列も同様です。 ハッシュは更にメモリを使います。 まだ行うことは残ってはいるものの、最近のリリースではこの問題に 対処しています。 たとえば 5.004 にあるように、重複したハッシュキーは全てのハッシュで 共有されます。 このため、(そのハッシュキーの格納のための)再割り付けの必要はありません。
substr() や vec() を使って配列をシミュレートすることで大幅に効率を 上げられることがあるでしょう。 たとえば 1000 個のブール値を持った配列は、 少なくとも 20000 バイトの空間を必要とします。 しかし、これを 125 バイトのビットベクターに置き換えることができます-- これで劇的にメモリを節約できます。 標準の Tie::SubstrHash モジュールもデータ構造の幾つかの型に対する助けを してくれるでしょう。 あなたがデータ構造のスペシャリスト(例えば行列など)モジュールとともに 仕事をしようとしているのなら、 C で実装されたモジュールは Perl で実装された等価なモジュールよりも 少ないメモリしか使わないでしょう。
試してみるべきもう一つの事柄は、あなたの使っている Perl がシステムの malloc を使っているのか Perl 組み込みの malloc を使っているのかを 知ることです。 いずれを使っているにしろ、別のものを使うようにしてみて それによる差を確かめます。 malloc に関する情報はソース配布にある INSTALL というファイルにあります。 perl -V:usemymalloc
とタイプすれば perl が使っている malloc がどちらであるかを知ることができます。
もちろん、メモリを節約する一番の方法はまず無駄なことをしないことです。 よいプログラミングプラクティスは以下のようなものを通じて得られています。
Don't slurp!@@@@@@@@@@ファイル全体を読み込まない!
ファイルを行単位で処理するときにファイル全体をメモリに読み込んでは いけません。 より具体的には、以下のようなループを使います:
#
# Good Idea
#
while (<FILE>) {
# ...
}
以下のような方式はよくないです:
#
# Bad Idea
#
@data = <FILE>;
foreach (@data) {
# ...
}
処理するファイルサイズが小さいなら、どちらの方法をとっても大きな 違いはありません。 しかし、ファイルが大きくなるにつれてその差は大きいものとなります。
Use map and grep selectively@@@@@@@@@@map と grep をうまく選んで使う
map と grep はどちらも LIST 引数を取るので、以下のようにすると:
@wanted = grep {/pattern/} <FILE>;
ファイル全体を読み込むことになります。 大きなファイルでは以下のようにループしたほうがよいです:
while (<FILE>) {
push(@wanted, $_) if /pattern/;
}
Avoid unnecessary quotes and stringification@@@@@@@@@@不必要なクォートと文字列化を避ける
本当に必要でないかぎりは大きな文字列をクォートしてはいけません。
my $copy = "$large_string";
このように書くと、$large_string のコピーを二つ($copy とクォートと) 作ります。一方以下のようにすると:
my $copy = $large_string;
コピーは一つしか作られません。
大きな配列の文字列化でも同じことが言えます:
{
local $, = "\n";
print @big_array;
}
これは以下のようなものよりメモリ効率がよいです:
print join "\n", @big_array;
または
{
local $" = "\n";
print "@big_array";
}
Pass by reference@@@@@@@@@@リファレンスで渡す
配列とハッシュは値ではなく、リファレンスで渡します。 これは一つの呼び出し/返り値で複数のリストやハッシュ(やその両方)を 渡す唯一の方法です。 また、これにより内容全てのコピーを作成しなくてすみます。 しかし、これにはいくばくかの判断が必要です。なぜならあらゆる変更が 元のデータに伝播するからです。 もし本当にコピーをいじりたい(修正したい)のなら、 コピーを作るためのメモリを犠牲にする必要があります。
Tie large variables to disk@@@@@@@@@@大きな変数をディスクに tie する
「大きな」データストア(利用可能なメモリ量を超えるようなもの)を 扱う時には RAM の代わりにディスクに保存するために DB モジュールの どれかを使うことを考えてください。 これはアクセス時間の低下を招きますが、おそらくは大量の スワッピングによってハードディスクが激しく動くよりましです。
はい。 Perl のガベージコレクションシステムは全てがうまくいくように 考慮されています。
sub makeone {
my @a = ( 1 .. 10 );
return \@a;
}
for ( 1 .. 10 ) {
push @many, makeone();
}
print $many[4][5], "\n";
print "@many\n";
(Michael Carman によって寄贈されました)
それは通常できません。 レキシカル(例えば my() 変数) に割り当てられたメモリは、たとえスコープから 外れても再請求や再利用されません。 これは変数がスコープ内に戻ってくる場合のために保存されます。 グローバル変数に割り当てられたメモリは undef() や delete() を使うことで (あなたのプログラム内で)再利用されます。
ほとんどのシステムでは、プログラムのために 割り付けたメモリは、決してシステムに返されることはありません。 これは、長期間動作しているプログラムが時々自分自身を 再起動する理由でもあります。 一部のオペレーティングシステム(特に大きなメモリの塊を 割り付けるときに mmap(2) を使うシステム)では、 最早使われていないメモリの塊を回収できますが、 そのようなシステムでは、perl を perl 自身ではなく OS の malloc を使うように設定し、コンパイルしなければなりません。
一般的に、メモリの確保と解放の問題は Perl においてはあまり気にする必要がある 問題ではありません。
"How can I make my Perl program take less memory?" も参照してください。
普通の Perl プログラムを速くしたり小さくしたりするための基準とは別に、 CGI プログラムには更に別の基準があります。 CGI プログラムは一秒に数回実行される可能性があります。 実行する度毎にスクリプトの再コンパイルとシステムメモリを 一メガバイト以上割りつけることが必要となります。 これは問題点となり得ます。 C へコンパイルすることは 助けにはなりません。 なぜなら、プロセスのスタートアップ時のオーバーヘッドが ボトルネックだからです。
このオーバーヘッドを避けるためのポピュラーな手段が二つあります。 解決策の一つは Apache HTTP サーバー(http://www.apache.org/ から入手可能)に mod_perl か mod_fastcgi のいずれかのプラグインモジュールを 取り込ませて実行させるというものです。
mod_perl と Apache::Registry モジュール(mod_perl と一緒に配布されて います)と組み合わせることで、httpd は組み込みの Perl インタプリタと 共に実行させるようになります。 これで、あなたのスクリプトは事前にコンパイルされ、 それを fork 抜きで同じアドレス空間で実行されるようになります。 Apatche エクステンションはまた、 Perl に内部サーバー API をアクセスすることを許可するので、 Perl で記述されたモジュールは C で書かれたモジュールができることはなんでも できるようになります。 mod_perl に関する詳細は http://perl.apache.org/ を参照してください。
FCGI モジュール(CPAN にあります)と mod_fastcgi モジュール(http://www.fastcgi.com で入手できます)は あなたの Perl プログラムのそれぞれを永続的 CGI デーモンプロセスにします。
これらの解決策は両方ともあなたの使うシステムで効果がない可能性があり、 また、あなたが書いた CGI プログラムに依存する方法なので、 注意して検査してください。
http://www.cpan.org/modules/by-category/15_World_Wide_Web_HTML_HTTP_CGI/ も 参照してください。
削除しましょう :-) まじめな話、様々な「セキュリティ」レベルを持った 幾つかの解決策があります(ほとんどは満足行くものではないでしょう)。
しかしながら、まず最初に、あなたは読み取り権限(read permission)を 落とすことはできません。 なぜなら、スクリプトのソースコードはコンパイルと解釈のために 読み取り可能でなければならない からです(これは CGI スクリプトのソースコードが web 上で、 読み取り可能であることとは違います-- ファイルシステムに対してアクセスできる人だけが読み取り可能です)。 ですから、権限の設定を少なくとも socially friendly な 0755 の レベルにしておく必要があります。
中にはこれをセキュリティ上の問題であると考えている人もいます。 あなたのプログラムが安全でないことを行った場合、 そして、人々がそのような安全でないことを暴露する方法を知らないことに 頼っているのなら、安全ではないのです。 誰かが、安全でないことを見つけだすこととソースを見ることなしにそれを 暴露することはしばしば可能となるのです。 セキュリティバグを直すのではなくてそのバグを隠すといった、 知られていないことに頼るセキュリティ(security through obscurity)は 小さなセキュリティの傷です。
ソースフィルタ(Perl 5.8 からは Filter::Simple と Filter::Util::Call は 標準配布物に含まれています)を使った暗号化を試すこともできます。 しかし、悪意在るプログラマーはそれを復号化できるかもしれません。 あなたは perlfaq3 で後述するバイトコードコンパイラとインタプリタを 使うことを試せるかもしれませんが、 探りたがりの人はそれを逆コンパイルできるかもしれません。 後述するネイティブコードコンパイラを試すこともできますが、 クラッカーはそれを逆アセンブルできるかもしれません。 これらの手段は、あなたのプログラムを手に入れようとする人達に様々な困難を もたらしますが、誰もそれを決定的に防ぐ障壁にすることはできないのです (Perl のみに限らず、あらゆる言語で真となります)。
Perl プログラムのソースを取り出すのはとても簡単です。 プログラムを perl インタプリタに渡して B:: 階層のモジュールを 使うだけです。 B::Deparse モジュールはソースを隠そうとするほとんどの試みを 打ち破るはずです。 繰り返しますが、これは Perl に限ったことではありません。
あなたが、誰かがあなたのプログラムを元になにか利益を 得るのではないかということを考えているのなら、 プログラムの最後の行を制限付きライセンスとすれば、 あなたに法的な安全性 (legal security)をもたらすでしょう。 あなたのソフトウェアをライセンスし、 “This is unpublished proprietary software of XYZ Corp. Your access to it does not give you permission to use it blah blah blah.” (本ソフトウェアは、XYZ コーポレイションにより作成された非公開の 独占的ソフトウェアです。 あなたがこれにアクセスすることは許されていません、云々) のような文章で味付けします。 もちろん私たちは弁護士ではありませんから、 あなたが確実に自分のライセンスが有効なものになるようにしたいのなら、 弁護士に会っておくべきでしょう。
(brian d foy によって寄贈されました)
一般的には、それはできません。 しかし、状況によっては可能な場合もあります。 人々は普通、ソースを提供することなく成果を配布したいためにこの質問をします; そしてほとんどの解決法は便利さのためにディスクスペースを犠牲にします。 ほとんどの解決法は単に最終製品に Perl インタプリタを同梱しているので、 どれを使ってもおそらく大して速度は向上しないでしょう (しかし "How can I make my Perl program run faster?" を参照してください)。
The Perl Archive Toolkit ( http://par.perl.org/ ) は Java における JAR のような Perl 版の類似物です。 自由に利用可能で、CPAN にあります ( http://search.cpan.org/dist/PAR/ )。
役に立つかもしれないいくつかの商用製品もありますが、それらのライセンスを 購入する必要があります。
ActiveState の The Perl Dev Kit ( http://www.activestate.com/Products/Perl_Dev_Kit/ ) は 「あなたの Perl プログラムを HP-UX, Linux, Solaris, Windows 用の実行 ファイルに変換します。」
Perl2Exe ( http://www.indigostar.com/perl2exe.htm ) は perl スクリプトを 実行可能ファイルに変換するコマンドラインプログラムです。 これは Windows と Unix プラットフォームの両方を対象としています。
OS/2 では単に:
extproc perl -S -your_switches
*.cmd
ファイルの先頭をこのようにするだけです(-S
は、 cmd.exe の "extproc" に関するバグのためです)。 DOS の場合は、適切なバッチファイルを作って ALTERNATE_SHEBANG
を 行うべきでしょう(詳細は、ソース配布キットにある dosish.h という ファイルを参照してください)。
Windows 95 や Windows NT で ActiveState の移植した Perl を使うのなら、 これは .pl
という拡張子を perl インタプリタに関連づけるように レジストリを変更します。 その他の移植になる perl を使うか、あるいはあなた自身が Windows に 移植された gcc(cygwin や mingw)を使って標準ソースから Perl を ビルドするというのであれば自分自身でレジストリを変更する必要があるでしょう。 .pl
とインタプリタを関連づけることによって、NT を使っている 人は install-linux.pl
を install-linux
のように起動することが 可能です。 NT では SET PATHEXT=%PATHEXT%;.PL
のようにします。
"Classic" MacOS では、perl のプログラムは適切な Creator と Type とを 持っているでしょうから、ダブルクリックするだけで MacPerl アプリケーションが起動するでしょう。 Mac OS X では、クリックできるアプリケーションは Wil Sanchez の DropScript utility: http://www.wsanchez.net/software/ を使って任意の #!
スクリプトから作成できます。
重要!: あなたが何をするにしても、どうか不満を感じないでください。 そして、あなたのプログラムが web サーバのために動作するようにさせるために perl インタプリタを cgi-bin ディレクトリに放り込むようなことは しないでください。 これは 非常に 大きなセキュリティ上のリスクとなります。 正しく動作させるための方法を考えるための時間を取ってください。
はい。 詳しくはperlrunを読んでください。 幾つかのサンプルを以下に挙げておきます(ここでは標準のUNIX シェル引用規則に 従っていると仮定します)。
# sum first and last fields
perl -lane 'print $F[0] + $F[-1]' *
# identify text files
perl -le 'for(@ARGV) {print if -f && -T _}' *
# remove (most) comments from C program
perl -0777 -pe 's{/\*.*?\*/}{}gs' foo.c
# make file a month younger than today, defeating reaper daemons
perl -e '$X=24*60*60; utime(time(),time() + 30 * $X,@ARGV)' *
# find first unused uid
perl -le '$i++ while getpwuid($i); print $i'
# display reasonable manpath
echo $PATH | perl -nl -072 -e '
s![^/+]*$!man!&&-d&&!$s{$_}++&&push@m,$_;END{print"@m"}'
そう、最後のは Obfuscated Perl コンテストにエントリーされてましたね :-)
この問題は、そういったシステムのコマンドインタプリタが、 一行野郎が作られた環境であるUNIXのシェルの引用規則とは異なるこということです。 一部のシステムでは、シングルクォートをダブルクォートに変更する必要が あるかもしれません(これは UNIX や Plan9 といったシステムでは してはいけません)。 同様に、%を%%に変更する必要もあるかもしれません。
例を挙げましょう:
# Unix (including Mac OS X)
perl -e 'print "Hello world\n"'
# DOS, etc.
perl -e "print \"Hello world\n\""
# Mac Classic
print "Hello world\n"
(then Run "Myscript" or Shift-Command-R)
# MPW
perl -e 'print "Hello world\n"'
# VMS
perl -e "print ""Hello world\n"""
問題は、これらの例の中に信頼できるものがないということです: コマンドインタープリタに依存します。 UNIX では、最初の二つはほとんどの場合動作するでしょう。 DOS では、どれも働かないかもしれません。 4DOS をコマンドシェルとしているのなら、以下のようにするのがよいと思います:
perl -e "print <Ctrl-x>"Hello world\n<Ctrl-x>""
Mac では、あなたが使っている環境に依存します。 MacPerl シェルや MPW は、制御キャラクターのような Mac の 非 ASCII キャラクターが自由に使えるという点を除いて、 UNIX シェルのように数種類の引用規則をサポートします。
ダブルクォート(")、シングルクォート(')、バッククォート(`)の 代わりに qq(), q(), qx() をそれぞれ使います。 これによって一行野郎を書くことが簡単になるかもしれません。
この件全てに関する一般的な解決策はありません。 ごちゃごちゃです。
[この回答の一部はKenneth Albanowskiから寄せられました]
モジュールなら、CPAN から CGI モジュールや LWP モジュールを入手しましょう。 教科書なら、本にある web stuff の特に決定的な二つを参照しましょう。 “Why do I get 500 Errors” (なんで 500 Errors になるの) “Why doesn't it run from the browser right when it runs fine on the command line” (なぜコマンドラインからだとちゃんと動くのに、ブラウザーからだと だめなんでしょうか)のように web に関連する問題や疑問は perlfaq9 か CGI MetaFAQ を参照してください:
http://www.perl.org/CGI_MetaFAQ.html
始めるにはよい場所は perltootです。 リファレンスとしてperlobj, perlboot, <perltooc>, <perlbot> が使えます。
Perl でのオブジェクト指向に関するよい本は Manning Publications が 出版する Damian Conway による "Object-Oriented Perl" か、 O'Reilly Media が出版する Randal Schwartz, brian d foy, Tom Phoenix による "Intermediate Perl" です。
もし Perl から C を呼び出したいのなら、perlxstut から始めて perlxs, xsubpp, perlguts へと進みます。 C から Perl を呼び出したいのなら、perlembed, perlcall, perlguts を 読みましょう。 すでにあるエクステンションの作者がどのようにそれを記述し、 どのように彼らの問題を解決したのかを見ることで多くのことが 学べるのだということを忘れないでください。
XS の力の全てが必要なわけではないかもしれません。 The Inline::C モジュールは Perl のソースの中に C のコードを直接書くことが できます。 これはこれが動作するための全ての魔法を扱います。 それでも少なくとも perl API の一部は学習する必要がありますが、XS サポート ファイルの複雑を扱う必要はありません。
CPAN から ExtUtils::Embed キットをダウンロードして、`make test'を 実行してください。 もしこのテストに合格したのなら、pod を何度も何度もくり返しくり返し 読んでください。 テストに失敗したなら、perlbug を読んで、perl -V
の出力と make test TEST_VERBOSE=1
の出力を添付してバグレポートを送ってください。
perl のすべてのエラーメッセージ、警告メッセージの説明テキスト付きのリストが perldiag にあります。 エラーメッセージを説明するために、splain プログラムを 使うこともできます(これは Perl と一緒に配布されています)。
perl program 2>diag.out
splain [-v] [-p] diag.out
あるいは、以下のようにしてメッセージを説明的にするようにプログラムを 変更します:
use diagnostics;
または
use diagnostics -verbose;
(brian d foy によって寄贈されました)
単に "MakeMaker" としてよく知られている ExtUtils::MakeMaker
モジュールは、 (典型的には Makefile.PL
という名前の) Perl スクリプトを Makefile に 変換します。 Unix ツール make
は Perl 配布を処理してインストールするための依存と 作業を管理します。
Copyright (c) 1997-2010 Tom Christiansen, Nathan Torkington, and other authors as noted. All rights reserved.
This documentation is free; you can redistribute it and/or modify it under the same terms as Perl itself.
Irrespective of its distribution, all code examples here are in the public domain. You are permitted and encouraged to use this code and any derivatives thereof in your own programs for fun or for profit as you see fit. A simple comment in the code giving credit to the FAQ would be courteous but is not required.