Perl

Perl
パラダイム マルチパラダイム
登場時期 1987年
最新リリース 5.30/ 2019年5月22日(2か月前) (2019-05-22
型付け 動的型付け
影響を受けた言語 AWKBASIC-PLUSCC++LispPascalsed, シェルスクリプト
影響を与えた言語 JavaScriptPHPPythonRubyPowerShell
プラットフォーム クロスプラットフォーム
ライセンス GNU General Public License, Artistic License
ウェブサイト https://www.perl.org/
テンプレートを表示

Perl(パール)とは、ラリー・ウォールによって開発されたプログラミング言語である。実用性と多様性を重視しており、C言語sedawkシェルスクリプトなど他のプログラミング言語の優れた機能を取り入れている。ウェブ・アプリケーション、システム管理、テキスト処理などのプログラムを書くのに広く用いられている。

言語処理系としてのperlはフリーソフトウェアである。Artistic LicenseおよびGPLのもとで配布されており、誰でもどちらかのライセンスを選択して利用することができる。UNIXWindowsなど多くのプラットフォーム上で動作する。

特徴[編集]

Hello world[編集]

print "Hello, world!\n"; 

文法[編集]

変数[編集]

変数としてスカラ、配列、ハッシュがある。変数名の前にシジル (sigil) と呼ばれる記号でこれらの変数を区別する。スカラのシジルは「$」、配列は「@」、ハッシュは「%」となっている。

変数は初期化の仕方によって、スコープが異なったものになる。

より高速で安全なmy宣言が導入されたPerl 5.0以降、local宣言は非推奨となっている[1]

下のコードは 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 条件 ; 

繰り返し[編集]

繰り返しには foreachforwhiledo - 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"; } 

forforeach は修飾子として後置することもできる。配列の各要素は順に$_という変数に渡される。

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 で飛び越すのと全く等価である。

サブルーチン[編集]

サブルーチンは以下のように定義する。

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' 

評価コンテキスト[編集]

評価コンテキスト、すなわち、構文上何が(リスト、数値、文字列、リファレンス、あるいは何もないのかが)要求されているかの違いにより評価値が変化する。 リストがスカラコンテキストで評価されるとリストの最後の要素に評価され、配列がスカラコンテキストで評価されると配列の長さに評価される。

$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 で判別することができる。したがって、コンテキストによって返り値を切り替えるような関数をユーザーが定義することもできる。

オブジェクト[編集]

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は持っている。

ワンライナー[編集]

コマンドラインからワンライナーと呼ばれる機能を使って、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 が有効になるため[2]、書くことが推奨されるのは use warnings のみとなる。

use 5.12.0; use warnings; 

Perl 5.10 で追加された機能[編集]

Perl 5.10.0以降では改行を自動的に出力するsayが使えるようになった。

use 5.10.0; # 5.10未満のPerlでの動作を制限するとともに、5.10での追加機能を有効に say "Hello, world!"; 

シェルからは-eオプションの代わりに-Eを使用すれば、追加機能を利用できる。

perl -E 'say "Hello, world!"'

その他の特徴[編集]

スレッド
Perlのスレッドはデータが丸ごとコピーされるという点で概念的にUNIXやLinuxforkに近い。iThreads(インタープリタスレッド)と呼ばれており、他のシステムにおけるどのスレッドとも実装は異なる。シグナルと同時に利用することで問題があるとも言われている。もともとWindows版にてforkのような実装を行うためのコードだったものから、発展している[3]。多くのLinuxディストリビューションではiThreadsをオンにして配布しているが、安全性重視をうたっているFreeBSDOpenBSDの標準ディストリビューションやOpenSolarisでは、iThreadsをオフにしている。
PerlIOレイヤ
入出力操作に手を加えることができる。各レイヤはC言語で実装できるため高速である。

モジュール[編集]

Perlプログラムには、モジュールによって機能を付加することができる。たとえば、他のプログラムやネットワークとの通信、各種ファイル形式の取り扱い、数学的な計算など、数多くのモジュールが存在する。PerlにはCPANというモジュールを体系的に管理するインターネット上のシステムがある。インターネットに接続しているならば、CPANにアクセスして、モジュールをインストールすることが可能である。

標準モジュール[編集]

Perlには標準で利用できるモジュールが数多く存在する。

代表的なCPANモジュール[編集]

テキスト処理
データベース
Webアプリケーション
  • CGI - CGIプログラミング
  • Plack - PSGIのリファレンス実装
  • Mojolicious - Webフレームワーク
  • Catalyst - Webアプリケーションフレームワーク
Webアクセス
データ記述言語の処理

歴史[編集]

Perlの歴史
バージョン 公開日 内容
1.0 1987年12月18日
  • 6台の VAX 機と6台の Sun 機のためのコンフィギュレーション管理制御システムのレポート作成ツールとして誕生した。
2.0 1988年6月05日
  • ヘンリー・スペンサー作の美しい正規表現ライブラリを Perl 風にアレンジし、導入した。
3.0 1989年10月18日
  • バイナリデータを処理できるようになった。
4.0 1991年3月21日
  • O'Reilly&Associates, Inc. より Programming perl が発売されたのに合わせて公開された。
5.0 1994年10月17日
  • リファレンスおよびオブジェクト指向に対応。
  • useが導入され追加モジュールの取扱いが大幅に強化された。
5.5.0 1998年7月22日
  • 正規表現の拡張、B::*モジュールによるフックのサポート、qr// 正規表現演算子の追加がなされた。
  • BeOS を含む幅広いオペレーティングシステムに移植された。
  • 日本語圏で最も重要なことは、このバージョンが JPerl がサポートする最後のバージョンということである。したがって、日本語情報処理において今なお使われている。
5.6.0 2000年5月22日
  • our文やウィークリファレンス、warningsプラグマの導入など、言語コアが大きく拡張された。
  • 試験的ながら Unicode のサポートを開始した最初のバージョン。
  • バージョン番号の構造を変更。サブバージョン(5.6.0の6に相当)が偶数のものが安定版、奇数のものが開発版を意味する。
5.8.0 2002年7月18日
  • 5.8系列の最新版は5.8.9(2008年12月14日)。
  • 汎用文字エンコーディング操作モジュール Encode が標準ライブラリに加えられ、Unicodeおよび Shift_JIS などの様々な文字エンコーディングに正式に対応した。
  • スレッドやPerlIOレイヤが導入された。
5.10.0 2007年12月18日
  • 公開日は Perl 1.0 の公開からちょうど20年目にあたる。
  • 静的変数を宣言する state 文や、switchに相当する given 文、say などの言語拡張が導入された。
  • 新しいキーワードの導入による互換性の問題に対処するため、新しいキーワードの導入を feature プラグマで制御できるようになった。
5.12.0 2010年4月13日
  • package のバージョン指定構文や未実装部分を表す...演算子(ヤダヤダ演算子)、後置の when 修飾子などが導入された。
  • 日付と時刻に関するコアモジュールが2038年問題に対応した。
5.14.0 2011年5月14日
  • Unicode 6.0 にほぼ完全に対応。
  • IPv6サポートの改善。
  • pushpopunshiftshifteachkeysvalues などの配列やハッシュを受け取る関数が、リファレンスを受け取ることができるようになった。
  • package パッケージ名 { ... }構文の追加。
  • 値を破壊せずに戻り値として返す正規表現オプションrが追加。
5.16.0 2012年5月20日
  • use バージョン番号文の動作が変更された。以前はスクリプトの実行に必要なPerlのバージョンを示すものだったが、「指定したバージョンよりも新しいバージョンの Perl で新たに実装された機能を無効化する」という動作になった。
  • __SUB__は現在実行中のサブルーチンに対する参照を返す。
  • feature プラグマでunicode_evalを有効にすると、文字列に対する eval は常に文字列を Unicode として扱う。またevalbytesを有効にすると、引数をバイト列として評価するevalbytes関数が利用できる。
  • substr は、左辺値もしくは潜在的に左辺値とみられるコンテキストで2つもしくは3つの引数付きで呼び出された場合、第一引数を変更する特殊な左辺値スカラを返す。
  • Unicode 6.1 対応も強化された。
  • デバッガ、CORE名前空間、XSインターフェイスなどでさまざまな機能強化が加わっている。
5.18.0 2013年5月18日
  • 実験的機能を利用するための新しい警告カテゴリexperimental::feature_nameが追加され、Perl 5.10 で加わったスマートマッチ演算子、レキシカルな$_がそのカテゴリに変更された。
  • ハッシュの際に使われるシードがランダム化され、keysvalueseach といったハッシュを利用する関数が返すキー/値の並び順が実行毎に異なるようになった。
  • Unicode 6.2 への対応、新しいDTraceプローブの追加、実験的機能としてレキシカルサブルーチンの追加などが行われた。\N{...}表現の扱いがいくつか変わっているほか、垂直タブがホワイトスペースとして扱われなくなっている点など、文字の扱いについていくつかの変更が加わった。
  • encodingCPANPLUSLog::MessageLog::Message::ConfigLog::Message::HandlersLog::Message::ItemLog::Message::SimpleObject::Accessorなどが廃止予定のモジュールとなった。
5.20.0 2014年5月27日
  • 実験的機能としてuse feature 'signature'によるサブルーチンシグネチャ、use feature 'postderef'によるPostfix Dereferencingと呼ばれる機能が追加された。Postfix Dereferencingを利用すると、いままで${ $sref } のように表記していたものが$sref->$* のように表記できるようになる。
  • 新たなスライス表記として、キーと値のペアを戻す%hash{…}%array[…]というスライス表記が加わった。
  • subキーワードのprototype属性がサポートされ、プロトタイプパーシングの一貫性も強化された。
  • 64ビットプラットフォーム対応が改善され、Perl配列が2**31以上の要素を保持できるようになった。
  • 正規表現エンジンは2**31以上の文字列に対応できるようになった。
  • Unicode 6.3 に対応した。
  • コアモジュールとしてIO::Socket::IPが追加された。
  • rand関数の仕様が変更された。
  • 一部のコマンドラインオプションの挙動が変更された。
5.22.0 2015年6月1日
  • ビット単位の演算子が導入された。
  • ダブルダイアモンド演算子が導入された。
  • 正規表現の\bバウンダリの機能が強化された。
  • 正規表現のキャプチャしない修飾子が追加された。
  • use re 'strict'がサポートされた。
  • Unicode 7.0がサポートされた。
  • POSIX 2008のロケール、通貨がサポートされた。
  • 古いプラットフォーム上のUTF-8判定が改善された。
  • リファレンスのエイリアスがサポートされた。
  • 引数なしのプロトタイプがサポートされた。
  • サブルーチンのconstアトリビュートがサポートされた。
  • filenoにディレクトリハンドルも指定可能になった。
  • Win32でリスト形式のパイプオープンが可能になった。
  • リスト代入の繰返し指定が可能になった。
  • InfNanの扱いが強化された。
  • 浮動小数点数の扱いが強化された。
  • InfNaNの文字列化は致命的エラーになった。
  • 実験的なCバックトレースAPIがサポートされた。
5.24.0 2016年5月9日
  • サブルーチンと数値計算が高速化された。
  • Unicode 8.0のサポートされた。
  • 実験的な扱いだった前方デリファレンスが本格サポートされた。
5.30.0 2019年5月22日
  • Unicode 12.1をサポート。

エピソード[編集]

Perlは当初、新約聖書マタイによる福音書13章46節の「高価な真珠」にちなんで真珠を意味する「pearl」と名付けられた。ラリー・ウォールは肯定的な意味を持つ短い名前を選びたいと考えていて、彼によれば3文字および4文字の単語を辞書から探したが良いのが見つからなかったということである。また、彼は妻のグロリアにちなんで名前を付けることも考えたが、家族の会話でまぎらわしいために却下となった。

Perlの正式なリリースの前に、すでに「pearl」という名前のプログラミング言語が存在する[1]ことに気づき、綴りを変更して「Perl」とした。このようにPerlは略語ではなく、もともと意味はないが、あとからいくつかの意味が考えられている。開発者ラリー自身によると、「practical extraction and report language」(実用的なデータ取得レポート作成言語)という意味を持ち、同時に 「pathologically eclectic rubbish lister」(病的折衷主義のガラクタ出力装置)[4]という少し皮肉な意味も込められている。

処理系[編集]

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と互換性を持たない。

Perlが利用されているアプリケーション[編集]

Perlが利用されている代表的なWeb アプリケーションや管理ツール。

Webアプリケーション[編集]

Webサービス[編集]

管理ツール[編集]

脚注[編集]

  1. ^ perlsub - perldoc.perl.org” (英語). 2011年7月21日閲覧。 “WARNING: In general, you should be using my instead of local, because it's faster and safer.”
  2. ^ http://perldoc.jp/docs/perl/5.12.0/perl5120delta.pod#Implicit32strictures
  3. ^ http://perldoc.perl.org/perlfork.html perlfork - Perl's fork() emulation
  4. ^ プログラミング Perl VOLUME 1 ISBN 4-87311-096-3

参考文献[編集]

関連項目[編集]

外部リンク[編集]