Perl

プログラミング言語 >>他のプログラミング言語 ■カテゴリ / ■テンプレート Perl（パール）とは、ラリー・ウォールによって開発されたプログラミング言語である。実用性と多様性を重視しており、C言語やsed、awk、シェルスクリプトなど他のプログラミング言語の優れた機能を取り入れている。ウェブ・アプリケーション、システム管理、テキスト処理などのプログラムを書くのに広く用いられている。 言語処理系としてのperlはフリーソフトウェアである。Artistic LicenseおよびGPLのもとで配布されており、誰でもどちらかのライセンスを選択して利用することができる。UNIXやWindowsなど多くのプラットフォーム上で動作する。 強力な文字列処理。正規表現をサポート 日本語をはじめとして世界中の言語を処理可能 連想配列（ハッシュ）をサポート 多次元データ構造が利用可能 自由度の高い文法。簡潔にプログラムを記述できる 高い後方互換性を持つ 数多くのオペレーティングシステムで利用可能 プログラムの実行には事前コンパイルは不要 スクリプト言語の中では高い処理速度を持つ Unicodeのサポート モジュールによる拡張が可能 有志によって開発された豊富なモジュール（CPANを参照） オブジェクト指向プログラミングのサポート リファレンスカウント方式によるガーベッジコレクション 例外処理のサポート クロージャのサポート リフレクションのサポート print "Hello, world!\n"; 「#」以降は行末までがコメントである。 # ここはコメントです。 変数としてスカラ、配列、ハッシュがある。変数名の前にシジル (sigil) と呼ばれる記号でこれらの変数を区別する。スカラのシジルは「$」、配列は「@」、ハッシュは「%」となっている。 変数は初期化の仕方によって、スコープが異なったものになる。 変数宣言をせずに初期化された変数 → 大域変数 local宣言をしてから初期化された変数 → 動的スコープで、ブロック内でのみ有効な局所変数 my宣言をしてから初期化された変数 → 静的スコープで、ブロック内でのみ有効な局所変数 より高速で安全なmy宣言が導入されたPerl 5.0以降、local宣言は非推奨となっている。 下のコードは my を使って変数を宣言し、同時に初期化する例である。local宣言もキーワードが異なるのみで同様である。 { my $num = 2 + 3; my $message = "Hello, world"; my @nums = (0, 1, 2); my %score = (english => 100, math => 80); # これらの変数は開き括弧「{」から閉じ括弧「}」までの間で有効。 } 配列およびハッシュの各要素はスカラであり、以下のようにアクセスする。ひとつの要素にアクセスするときは、変数が配列やハッシュであっても「$」を使う。 $nums[0]; # 0 $score{math} # 80 スカラには数値、文字列などを格納することができる。 $jackBauer = 24; $pi = 3.14159265358979; $vulcanSalute = 'Live long and Prosper!'; 条件分岐を行うには「if ～ elsif ～ else」を利用する。 if (条件1) { ～ 処理1が真の場合の処理 ～ } elsif (条件2) { ～ 条件1が偽で、条件2が真の場合の処理 ～ } else { ～ 条件1も条件2も偽の場合の処理 ～ } 条件分岐後の処理は文がひとつの場合でも必ず中括弧「{～}」で囲まねばならない。 ifは修飾子として後置することもできる。この場合は逆に中括弧で囲むことはできず、ひとつの文しか指定できない。 print 'Hello' if 条件 ; ifに対してunlessが存在する。ifとは反対に条件が満たされなかった場合に処理が実行される。 unless (条件) { ～ 条件が偽の場合の処理 ～ } print 'Hello' unless 条件 ; 繰り返しには foreach、for、while、do - while を利用する。 foreach はすべての配列の要素を順番に処理したい場合に利用される。 my @names = ('Tom', 'Mike', 'Bred'); foreach my $name (@names) { # 処理 } forは規則性のある仕方で変数を変化させるときに使う。 $sum = 0 ; for (my $i = 0; $i < 10 ; ++$i) { $sum += $i; } for ($node = $doc->getFirstChild ; $node ; $node = $node->getNextSibling) { print $node->getNodeValue, "\n"; } for と foreach は修飾子として後置することもできる。配列の各要素は順に$_という変数に渡される。 print $_ for @names; while は処理を始める前に条件を検査し、条件が満たされる間、処理が繰り返される。 while (条件) { # 処理 } while には、次の繰り返しに移る前に行いたい処理を continue ブロックにまとめて書くことができる。 while (条件) { # 処理 } continue { # 次の繰り返しの前に行う処理 } do - while は処理を行った後に条件を検査し、条件が満たされる間、処理が繰り返される。 do { # 処理 } while (条件) ; last で繰り返しを抜けることができる。while 文で continue ブロックがある場合には、continue ブロックの内容は実行されない。 foreach my $v (@values) { # 0 ≦ $v でない値を見つけたら、その時点で繰り返しをやめる。 last unless 0 <= $v ; } next で次の繰り返しに移行する。next では、while 文で continue ブロックがある場合には、次の繰り返し処理に移る前に continue ブロックの内容が実行される。for 文の場合、次の繰り返し処理に移る前に for 文の3番目の引数文が実行される。 foreach my $v (@values) { # 0 ≦ $v でない値を見つけたら、次の繰り返し処理に移る。 next unless 0 <= $v ; } redo で次の繰り返しに移行する。redo では、while 文で continue ブロックがある場合には、次の繰り返し処理に移る前に continue ブロックの内容は実行されない。foreach でも（制御）変数の値は変更されずに最初から同じ処理を繰り返す。for 文の場合、次の繰り返し処理に移る前に for 文の3番目の引数文が実行されない。実のところ redo は繰り返し文専用の制御構造ではなく、ブロック（{ ～ } で囲われたところ）の内側であればどこでも使え、ブロックの先頭に goto で飛び越すのと全く等価である。 任意の場所に飛び越しを行うには goto を利用する。goto の後ろには飛び越し先ブロックのラベルを書く。goto 文は繰り返し文の中やブロックの内側でなくとも、プログラム中のどこにでも記述できる。しかし、繰り返し文の中での飛び越しにはlast、next、ブロックの内側であれば redo を使う方がコードが読みやすくなるので、gotoが使われることは少ない。 goto destination ; print "この print 文は実行されない。\n" ; destination: { print "飛び越し先ブロック\n" ; } サブルーチンは以下のように定義する。 sub hello { print "Hello, world!\n"; } 呼び出しは以下のとおり。 hello(); hello; &hello(); サブルーチンは関数としても機能する。その場合、最後に評価した値ないしreturnで指定された値が戻り値となる。 sub hello { return "Hello, world\n"; # return は省略可能 } print hello(); # "Hello, world!" と表示 引数は特殊変数@_に格納される。 # 丁寧に書いた例 sub mul { my ($left, $right) = @_; return $left * $right; } sub mul { $_[0] * $_[1] }; # こうも書ける データに直接アクセスするのではなく、データの存在するメモリアドレスをスカラ値として定義するリファレンスを使用することができる。スカラ、配列、ハッシュ、ファイルハンドル、サブルーチンのリファレンスが存在する。 1 my $scalar_ref = \$scalar; # スカラへのリファレンス 2 my $array_ref = \@array; # 配列へのリファレンス 3 my $hash_ref = \%hash; # ハッシュへのリファレンス 4 my $sub_ref = \&sub; # サブルーチンへのリファレンス 5 open my $fh, '<', $file; # $fhがファイルハンドルへのリファレンス 6 open my $fh, '<', $file; # $fhがファイルハンドルへのリファレンス 7 open my $fh, '<', $file; # $fhがファイルハンドルへのリファレンス 8 open my $fh, '<', $file; # $fhがファイルハンドルへのリファレンス 9 open my $fh, '<', $file; # $fhがファイルハンドルへのリファレンス 参照元にアクセス、すなわちデリファレンスするには、シジルを変数名の頭につければよい。 my $scalar = $$scalar_ref; my @array = @$array_ref; my %hash = %$hash_ref; my $sub = &$sub_ref(2, 3); # サブルーチン呼び出し -- $sub には戻り値が入る ただし、配列・ハッシュおよびサブルーチンへのリファレンスに関しては、その要素にアクセスするのに（あるいはサブルーチンを呼び出すのに）->を使うことができる。 $array_ref->[0]; $hash_ref->{two}; $sub_ref->(2, 3); 配列・ハッシュについては、配列名・ハッシュ名が定義されておらず、リファレンスからのみアクセスできる無名配列・無名ハッシュを作成することができる。 my $array_ref = [0, 1, 2]; # 無名配列 my $hash_ref = {zero => 0, one => 1, two => 2}; # 無名ハッシュ また、無名サブルーチンを作ることもできる。 my $sub_ref = sub { $_[0] * $_[1] }; print $sub_ref->(2, 3), "\n"; # 6 を出力 print &$sub_ref(2, 3), "\n"; # こうも書けるが、読みにくいためあまり使われない 参照元のデータタイプを調べるには、refを使う。 ref 1; # '' ref $scalar_ref; # 'SCALAR' ref $array_ref; # 'ARRAY' ref $hash_ref; # 'HASH' 参照元がオブジェクトの場合、refはそのオブジェクトが所属するパッケージ名（クラス名）を返す。 ref Foo::Bar->new(); # たいてい 'Foo::Bar' モジュールを利用するにはuseを使用する。 use Net::FTP; モジュールの読み込みと共に関数をインポートしたい場合は、モジュール名に続いて、関数名を並べるのが一般的である。 use File::Basename 'fileparse'; 評価コンテキスト、すなわち、構文上何が(リスト、数値、文字列、リファレンス、あるいは何もないのかが)要求されているかの違いにより評価値が変化する。 リストがスカラコンテキストで評価されるとリストの最後の要素に評価され、配列がスカラコンテキストで評価されると配列の長さに評価される。 $x = ("a", "b"); #リストをスカラコンテキストで評価 print $x; # b を出力 @a = ("a", "b"); $x = @a; #配列をスカラコンテキストで評価 print $x; # 2 を出力 ($x, $y) = @a; #リストコンテキスト print $x; # a を出力 意味が大きく変わる表現も存在する。 @match = ("123 a 56 x" =~ m/\d+/g); #リストコンテキスト (全てを一度にマッチ） # @match => ("123", "56") $match = ("123 a 56 x" =~ m/\d+/g); #スカラコンテキスト (順次マッチ） # $match => "1" ブロックを呼び出したコンテキストを wantarray で判別することができる。したがって、コンテキストによって返り値を切り替えるような関数をユーザーが定義することもできる。 例外を発生させるにはdie関数を使う。例外が発生するとプログラムはメッセージを出力して終了する。 die "例外が発生しました。"; 例外をキャッチするには「eval { };」を使用する。例外が発生した場合は特殊変数「$@」にメッセージが代入される。「$@」の値を調べることで例外が発生した場合の処理を記述できる。 eval { 例外が発生する処理 }; if ($@) { 例外が発生した場合の処理 } Perlにおけるパッケージとは、一般的に名前空間と呼ばれる機能のことである。パッケージを宣言するには「package」を使う。 package Foo; パッケージ内で宣言されたパッケージ変数とサブルーチンはパッケージに属するものとなる。パッケージ変数を宣言するには「our」を使う。パッケージ変数には大文字を利用するのが一般的である。 package Foo; our $NUM = 1; sub sum { ... } package Bar; our $NUM = 2; sub sum { ... } 上記において、Fooパッケージのパッケージ変数$NUMとBarパッケージのパッケージ変数$NUMはまったく別の変数である。またFooパッケージのsumとBarパッケージのsumはまったく別のサブルーチンである。パッケージ変数やサブルーチンはパッケージごとに定義することができる。 自パッケージ内であれば、パッケージ名の指定を行わずに、パッケージ変数やサブルーチンを参照することができる。 package Foo; our $NUM = 1; sub sum { ... } print $NUM; print sum(); 他のパッケージから参照するには、完全修飾を行う必要がある。mainはデフォルトのパッケージをあらわす。 package Foo; our $NUM = 1; sub sum { ... } package main; print $Foo::NUM; print Foo::sum(); Perlでは、上記のリファレンスとパッケージを組み合わせることにより、クラスベースのオブジェクト指向を実現している。 package Class; # コンストラクタ sub new { my $class = shift; my $self = {@_}; bless $self, $class; } # アクセサ sub meth { my $self = shift; $self->{meth} = shift if @_; $self->{meth}; } オブジェクトを使うときは以下のようにする。 my $obj = Class->new(meth => 'od'); warn $obj->meth; # 'od'; なぜこれが動くのかというと実は、Perlはこれを以下のように解釈している。 my $obj = Class::new('Class', meth => 'od'); warn Class::meth($obj); Perlにおいて、クラスはただのパッケージであり、オブジェクトはただのblessされたリファレンスであり、そしてメソッドは第一引数にオブジェクトをとるただのサブルーチンである。これはPerl 4との互換性を考慮してこのような「後付け」の設計となったのだが、驚くべき柔軟性を示す。これだけで継承も委譲も出来てしまうのだ。最初からオブジェクト指向のもとに設計された言語から見ると見た目は変であるが、それらの言語に勝るとも劣らないオブジェクト機能をPerlは持っている。 ドキュメンテーションはPODを用いて記述する。 =head1 NAME foo.pl =head1 DESCRIPTION this script is ... =cut コマンドラインからワンライナーと呼ばれる機能を使って、Perlを実行することができる。 perl -e 'print "Hello, world!\n"' perl -le 'print "Hello, world!"' 以下の2行をプログラムの先頭に記述することが強く推奨されている。 use strict; use warnings; strict は潜在的な問題をコンパイル時に調べるためのものであり、warnings は警告の出力を有効にするためものである。perl インタプリタを起動するときのコマンドラインオプションの -w とは似ているが同じではない。warnings の方がより細かいので use warnings を使って -w オプションは省略すればよい。 また、use で 5.11.0 以降のバージョン番号を指定した場合にはデフォルトで use strict が有効になるため、書くことが推奨されるのは use warnings のみとなる。 use 5.12.0; use warnings; Perl 5.10.0以降では改行を自動的に出力するsayが使えるようになった。 use 5.10.0; # 5.10未満のPerlでの動作を制限するとともに、5.10での追加機能を有効に say "Hello, world!"; シェルからは-eオプションの代わりに-Eを使用すれば、追加機能を利用できる。 perl -E 'say "Hello, world!"' PODによる記法を用いると複数行コメントを書くことができる。(あまり利用されない) =begin comment ここは コメント です。 =end comment スレッド Perlのスレッドはデータが丸ごとコピーされるという点で概念的にUNIXやLinuxのforkに近い。iThreads（インタープリタスレッド）と呼ばれており、他のシステムにおけるどのスレッドとも実装は異なる。シグナルと同時に利用することで問題があるとも言われている。もともとWindows版にてforkのような実装を行うためのコードだったものから、発展している。多くのLinuxディストリビューションではiThreadsをオンにして配布しているが、安全性重視をうたっているFreeBSDやOpenBSDの標準ディストリビューションやOpenSolarisでは、iThreadsをオフにしている。 PerlIOレイヤ 入出力操作に手を加えることができる。各レイヤはC言語で実装できるため高速である。 Perlプログラムには、モジュールによって機能を付加することができる。たとえば、他のプログラムやネットワークとの通信、各種ファイル形式の取り扱い、数学的な計算など、数多くのモジュールが存在する。PerlにはCPANというモジュールを体系的に管理するインターネット上のシステムがある。インターネットに接続しているならば、CPANにアクセスして、モジュールをインストールすることが可能である。 Perlには標準で利用できるモジュールが数多く存在する。 base - クラスの継承 Benchmark - ベンチマーク Carp - 呼び出し元の観点で例外を発生 Cwd - カレントディレクトリのパスを取得 Data::Dumper - 変数の内容を出力 Digest::MD5 - MD5値 Digest::SHA - SHA-1/224/256/384/512 Encode - 文字列のエンコード・デコード utf8 - utf8プラグマ Exporter - 関数のエクスポート File::Basename - ファイルのベース名とディレクトリ名の取得 File::Copy - ファイルの移動とコピー File::Path - 複数階層のディレクトリの作成と削除 File::Spec - ファイル名に対する移植性のある処理 File::Temp - 一時ファイルの生成 FindBin - スクリプトが存在するディレクトリのパスの取得 Getopt::Long - コマンドライン引数の処理 lib - モジュールの検索パスを追加 List::Util - 配列に対する処理 Net::FTP - FTPクライアント Scalar::Util - スカラ値のユーティリティ Storable - データの直列化 Sys::Hostname - ホスト名の取得 Time::Piece - 日付・時刻の扱い IO::Socket::INET - ソケット テキスト処理 Text::CSV - CSVファイルの解析 Text::Diff - diffコマンド Template Toolkit - テンプレートシステム データベース DBI - 汎用データベースインタフェース Webアプリケーション CGI - CGIプログラミング Plack - PSGIのリファレンス実装 Mojolicious - Webフレームワーク Catalyst - Webアプリケーションフレームワーク Webアクセス LWP::UserAgent - WWWクライアント データ記述言語の処理 XML::Simple - XMLをPerlのデータ構造に変換 XML::LibXML - XMLのサポート JSON - JSONのサポート YAML - YAMLのサポート Perlは当初、新約聖書のマタイによる福音書13章46節の「高価な真珠」にちなんで真珠を意味する「pearl」と名付けられた。ラリー・ウォールは肯定的な意味を持つ短い名前を選びたいと考えていて、彼によれば3文字および4文字の単語を辞書から探したが良いのが見つからなかったということである。また、彼は妻のグロリアにちなんで名前を付けることも考えたが、家族の会話でまぎらわしいために却下となった。 Perlの正式なリリースの前に、すでに「pearl」という名前のプログラミング言語が存在する[1]ことに気づき、綴りを変更して「Perl」とした。このようにPerlは略語ではなく、もともと意味はないが、あとからいくつかの意味が考えられている。開発者ラリー自身によると、「practical extraction and report language」（実用的なデータ取得レポート作成言語）という意味を持ち、同時に 「pathologically eclectic rubbish lister」（病的折衷主義のガラクタ出力装置）という少し皮肉な意味も込められている。 Perlという名称の記述においては、若干の注意が必要である。プログラミング言語としてのPerlを示すときは「Perl」というように、頭文字を大文字にして固有名詞であることをはっきりさせる。この「Perl」という表記では処理系のことは含まれない。Perl 5の現在開発されている唯一の処理系は「perl」という、すべて小文字で記述される名前の処理系である。一般に「perlだけがPerlを解釈することができる」という表現がなされる。「PERL」のようにすべてを大文字にするのは誤りである。 このようにPerl 5現在において、Perlとは言語の名前であると同時に唯一の処理系の名前でもある。この処理系はC言語で書かれている。スクリプトは実行前に仮想機械向けにコンパイルされ、コンパイルされたバイトコードが実行される（ランタイムコンパイル）。そのため、厳密にはインタプリタとは異なる。 Pythonのように一旦生成したバイトコードを保存して再利用することは少ないが、これは現在のPerlのランタイムコンパイルが高速で、バイトコードから実行するメリットがあまりないことが理由の一つである。コンパイル済みコードの再利用としてはむしろmod_perlのような形式が好まれている。 PAR (Perl Archive Toolkit) というPerlスクリプトを実行環境ごとアーカイブし、単一のファイルにまとめるためのツールキットも存在する。JARのPerl版と考えてよい。実行可能ファイルを作ることもできるため、アプリケーションの配布に適する。しかしその場合はPerl実行環境をまるごと含むため、ファイルサイズが大きくなる傾向にある。 Perlの姉妹言語としてPerl6が存在する。Perl6はParrotというバーチャルマシンの上で動作する。現在、ParrotCodeへのコンパイルを行うRakudo Starという処理系やHaskellで書かれたPugsという処理系などの複数の実装が公開されている。なおPerl6はPerlと互換性を持たない。 Web アプリケーションや管理ツールの多くが Perl で書かれている。 Movable Type TWiki Bugzilla SpamAssassin Catalyst フレームワーク automake DuckDuckGo ^ “perlsub - perldoc.perl.org” (英語). 2011年7月21日閲覧。 “WARNING: In general, you should be using my instead of local, because it's faster and safer.” ^ http://perldoc.jp/docs/perl/5.12.0/perl5120delta.pod#Implicit32strictures ^ http://perldoc.perl.org/perlfork.html perlfork - Perl's fork() emulation ^ プログラミング Perl VOLUME 1 ISBN 4-87311-096-3 ラリー・ウォール、ジョン・オーワント、トム・クリスチャンセン著、近藤嘉雪訳『プログラミング Perl』VOLUME 1 (ISBN 4-87311-096-3), 2 (ISBN 4-87311-097-1), オライリー・ジャパン、2002年 ラリー・ウォール Artistic License グルー言語 スクリプト言語 軽量プログラミング言語 The Perl Programming Language - Perlの公式サイト Perl 6 Programming Language - Perl6の公式サイト Perl programming documentation - Perlの公式ドキュメント perldoc.jp - Perlの公式ドキュメントの日本語訳 CPAN - Perlのモジュールの配布を行うサイト Perl.com - オライリーによるPerlのウェブサイト ActivePerl - ActiveState社のPerlディストリビューション。Win32版はWindows環境で最も利用される。 Chocolate Perl - Perlのディストリビューションのひとつ Vanilla Perl - Perlのディストリビューションのひとつ Strawberry Perl - Perlのディストリビューションのひとつ PSGI/Plack - WSGIのPerlによる実装 Japan Perl Association - YAPC::Asiaを主催する一般社団法人