初歩の「Perl」「Python」「Ruby」The Rational Edge(2/2 ページ)

» 2007年08月28日 12時00分 公開
[Gary Pollice(ワーチェスター工芸研究所業務学教授),@IT]
前のページへ 1|2       

共通するいくつかの仕様

 どの言語にも計算フローをコントロールし、データを表現する機能が必要だ。ここで解説している3つの言語も、すべて同様の機能を持っている。これらはさまざまなタイプの数値(整数や浮動小数点)、文字、文字列などをサポートする。さらに、配列やハッシュなどの組み込みデータ構造も持っていて、レコードライクな構造も何らかの形でサポートする。

 Cのような言語に慣れているプログラマーの多くなら、ディクショナリもしくは連結配列とも呼ばれるハッシュのことはご存じかもしれない。ハッシュは配列のような構造だが、その中の値には、数値の位置ではなくキーによってアクセスする。従って、中に自分が受け持つクラスの生徒全員の期末の成績が格納される「成績」というハッシュがある場合、J. Doeの成績を「A」にするには次のような命令文を使う。

grades['J. Doe'] = 'A'

 ハッシュは、明確な順番に並んでいないデータにアクセスする際に極めて有効だ。Mapクラスを使ったことのあるJavaプログラマーなら、ハッシュは使い慣れているだろう。

 ここの3つの言語はさらに、どれもが正規表現とパターンマッチングをサポートしている。多くのシステム管理作業では、システムファイル、ログファイル、コンフィギュレーションファイルなどのテキストの操作が必要になる。この情報の大半は、プログラムが正規表現を使って中の情報を見つけられるようフォーマットされている。例えば、「str」という文字列に「IBM」というサブストリングが入っていて、必ずしもその直後ではないものの、「Rational」というサブストリングが続いているかどうかを判断したい場合は、次のような小さいPerlプログラムを書く。

$str = 'This is a sentence containing IBM and Rational in it.';
if ($str =~ /IBM.*Rational/) {
    print "True"
} else {
    print "False"
} 

 ここでは、スラッシュの間の文字がシンプルなパターンを構成している。このパターンの中の唯一の特殊文字が「.*」で、これは0個以上のあらゆるタイプの文字を示している。上のプログラムは「True」をプリントする。UNIXライクなシステムを使ったことのあるプログラマーなら、大半は正規表現をよく知っているはずだ。これらはかなり分かりにくいが、テキスト処理能力に優れているので、学習するだけの価値はある。

 ここで説明している言語はどれも、さまざまなタイプの入出力をサポートする。また、どれもきちんとした帳票を出力できるよう、データフォーマット機能を搭載している。実際、Perlが最初にリリースされた当初は、「Perl」は「Practical Extraction and Report Language(実用的抽出・報告書作成用言語」の略だと思われていた。だが実際のところ、「Perl」に特別な意味はない。何かの頭文字を取ったものではないのだ。Wall氏は当初、自分が作った言語にマタイ伝の高価な真珠の寓話から取って「Pearl」という名前を付けるつもりだったが、PEARLという別の言語の存在を知り、自分の言語にはPerlという名前を付けた。

違いを評価する

 これら3つの言語には共通する仕様がまだたくさんあるが、本稿の残りの部分では各言語を特徴付ける違いをいくつか説明したい。これらの違いのいくつかは、その言語の長所となることもあれば、短所を意味する場合もある。そしてもちろん、筆者の感想のいくつかは完全に主観的だが、あとはもう少し深く考えられた理論に基づいている。

 筆者にとって、コードの読みやすさは常に不満の種だった。Guido van Rossum氏と同様、筆者も、明確さを犠牲にしてまで自分のプログラムのパフォーマンスを極限まで高めようと試みることより、コードを読んで理解できることの方を評価する。プログラムを可能な限り最適化することが必要なケースも確かにあるが、必然性が確認できなければ筆者はそのようなことはしない。

 ここで説明している言語は、どれも読みやすく書くことができる。しかし、そのように書けるからといって、実際に読みやすいものができるとは限らない。筆者は先に、Pythonのコードは字下げが必要だと説明した。筆者はいつも字下げをしているので、この点に関しては問題はない。しかし、「Pythonコードの2つの例」で指摘したようなミスの可能性は問題だ。どの言語も、その内部でのプログラム開発をサポートする統合開発環境(IDE)を1つ以上用意している。Eclipseプラットフォームには、これらを1つ1つサポートするプラグインがある。IDEやシンタックス依存型エディタがあれば、字下げのような問題も対応される。

 読みやすさにだけ関していえばPythonが一番であり、Perlが最下位になる、というのが筆者の意見だ。筆者はPerlを「開発専用」言語に分類することが多い。Perlのプログラマーは、最もコンパクトで簡潔なコードの開発を高く評価する文化を取り入れたのだ。これは通常、読みやすさを犠牲にして成り立つものだ。これに加え、Perlには特殊な変数を使う問題がある。いったんPerlの慣用語法に慣れてしまえば、特殊な変数の多くも分かるようになるが、Perlをまだ学習中だと、Perlプログラムを読むことが象形文字を解読するに等しくなる。Perlは、見た目がかっこよく、一見して理解できないコードで非常に巧妙な処理ができることを技術屋が喜び勇んで見せびらかせる言語だ。下記のスクリプトは、非常に小さいPerlのコードがどれほど不可解かを示している。[注7


[注7]「rename」と呼ばれるこのスクリプトは、http://user.it.uu.se/~matkin/programming/PERL/にある。このWebページには、これはPerlの生みの親であるLarry Wall氏が書いたものだとある。


1 #!/usr/local/bin/perl
2 $op = shift;
3 for (@ARGV) {
4      $was = $_;
5      eval $op;
6      die $@ if $@;
7      rename($was,$_) unless $was eq $_;
8 }
  8行のPerlコード

 では、これを見ながら、Perlのプログラマーでないと分からないと思われる部分をいくつか考えていこう。2行目は、引数から最初の単語をスクリプトにシフトし、これをスカラー変数の「op」に入れる。引数リストから値がシフトされるのは、シフトファクションに引数が渡されないためであることは分かる。スクリプトの最も外側でこうなった場合は、自動的に引数リストがパラメータであると仮定される。また、頭に「$」が付いているので「op」がスカラー変数であることも分かる。もし頭に「@」が付いていたら、これは配列となり、「%」が付いていたらハッシュになる。

 3行目から8行目まではループだ。このループは配列の「ARGV」を使って繰り返し処理を行うが、これは、コマンドラインからスクリプトに渡された引数の残りだ。4行目は、引数リストの次の項目に変数をセットする。「$_」も特殊変数の1つで、場所が変わればその意味も変わってくる。

 5行目と6行目はおそらく最も混乱するだろう。5行目は、ダイナミック言語で最もパワフルな機能の1つである「eval」命令文を使っている。これにより、読み込んだ、もしくは作成したテキストを、それがプログラムであるかのように実行できるようになる。では、何が実行されるのだろうか? 「op」に移動した最初の引数だ。このスクリプトの目的が理解できなかったら、何が起こっているか理解するのは難しいだろう。この行は、最初の引数がある値(シフトした引数で、まだ$_の中にある)に適用できるPerlの式であることを示唆している。予想されるのは、この式が、オペランドの中にある「txt」を「pl」で入れ替える「s/txt/pl/」のような何らかの正規表現の代用であることだ。これとオペランドを比較すれば、これがオペランドの中の所定の場所で変更を行う。

 評価中にエラーが発生したら、6行目がエラーメッセージ(特殊変数の$@に格納されている)を表示しスクリプトを終了させる。

 これはわずか数行のコードだが、かなりパワフルなスクリプトだ。同様に、Linuxシステムでは次のようなコマンドラインを入力し、一連のファイルの年の部分だけ変更することもできる(スクリプトの名前が「rename.pl」で、これが実行イメージであると仮定している)。

rename.pl s/2006/2007/ HW1-2006.txt HW2-2006.txt HW3-2006.txt

 一般的な正規表現とLinuxコマンドを併用すれば、その出力をファイル名一覧にリダイレクトすることができる。

 そのパワーと問題の両方を読者に説明したかったので、ここまではPerlにかなりの時間を割いてきた。また、読者の皆さんには筆者がPerlを完全に避けているとは思ってほしくない。これらのコードはすべて、筆者が自分のPerl修士論文用に書いたものだ。これは、テキストの操作や、CやC++などのほかの言語でソースコードを生成するのに素晴らしい言語だった。この目的であれば、筆者はいまでもPerlを選ぶが、個人的にはRubyの方が不安がない。

 PythonはPerlの機能を持っているが、プログラムを操作するためのプログラムが書ける「introspection」(Javaのreflectionのようなもの)や、「lambda」(anonymous)ファンクションなど、オブジェクト指向のプログラマーを喜ばせるであろう先進機能をほかにも数多く搭載している。さまざまなプログラミング方法論を使うのが好きな言語の達人なら、Pythonは素晴らしい選択肢になる。また、各種オーディオファイルフォーマットやビデオファイルなどの先進技術との連動機能を実現する多くのモジュールやライブラリにもサポートされている。ロボット工学調査用の開発プラットフォームである「Pyro」など、Pythonには拡張版が複数ある。[注8


[注8]Pyroに関する情報はhttp://pyrorobotics.org/を参照。


 下記のコードは、前述のPerlプログラムと同じでPythonで書かれたプログラムとなっている。複数の正規表現のマッチングに応じて、ディレクトリ内のファイル名を変更する。[注9


[注9]このプログラムはhttp://www.palovick.com/code/python/python-rename-files.phpにある。


1 #!/usr/local/bin/python
 2
 3 # Python Rename File 1.0 
 4 # Author: Douglas Palovick
 5 # License: GPL http://www.gnu.org/licenses/gpl.txt
 6
 7 import re, os
 8 rxin = raw_input('enter a regex to search for:\n')
 9 foo = re.compile(rxin)
10 newname = raw_input('enter a new base name:\n')
11 a = 0
12 for fname in os.listdir(os.getcwd()):
13     allowed_name = re.compile(rxin).match
14     if allowed_name(fname):
15         # newfname = string.lower(re.sub(foo,
16                                   # '', fname))
17         # b = (newname + str(a))
18         a += 1
19         c = os.path.splitext(fname)
20         b = (newname + str(a) + c[1])
21         os.rename(fname, b)
  Pythonで書かれたプログラム

 このプログラムはPerl版ほど簡潔ではなく、特殊な変数や仮定もない。ここでいくつか指摘しておきたい。まず、9行目をご覧いただきたい。これは、正規表現モジュール(re)を使い、ユーザーが8行目で入力した正規表現から、コンパイルされた正規表現を生成している。Javaのプログラマーなら、Java Matcherクラスとの類似点が分かるだろう。コードの残りの部分についてはご自身で調べていただきたい。


 上の例は、いずれもPerlやPythonの本来の力を明らかにするものではなく、筆者も短い文章でそれを狙っているわけではない。しかし、これらの例や比較が読者の刺激になり、さらに詳しい内容を探り出すきっかけになることを期待している。Rubyの解説は次回以降とする。次回はRailsフレームワークも見ていく。

 最後に、本稿にはzipファイルのアーカイブが用意されていることを指摘しておきたい。これには4つのファイルが含まれている。1つは、筆者の新旧の教え子に出した問題を解説するPDFファイルだ。彼らには少なくとも1つの言語の経験があり、指定したダイナミック言語のいずれか1つを使ってこの問題を解くプログラムを書くよう指示を出した。説明に付属している3つのファイルは、彼らのソリューションだ。これらを見て、どれが好みか考えていただきたい。


本記事は「The Rational Edge」に掲載された「Dynamically speaking」をアットマーク・アイティが翻訳したものです。


「The Rational Edge」バックナンバー
前のページへ 1|2       

Copyright © ITmedia, Inc. All Rights Reserved.

注目のテーマ