Perl/CGIプログラムの関数ライブラリ
今回は、関数ライブラリについて学習していきます。
編集前記
今回の編集前記は、プログラムの世界の中で Perlプログラム というのはどのあたりに位置するものなのかということについてお話します。
Perl/CGIプログラムをコーディングしていく以前の話で、ものすごく基本的なことですが、大切なことですから知っておいても損はありません。
現代に存在するたくさんのプログラミング言語の中で、Perlプログラムというのは、いったいどのあたりに位置するものなのか?
今回は、そんな漠然とした疑問を解決していくことから始めましょう。
まずは、機械の頭脳が理解できる命令を機械語といいます。
ここで言う機械というのは、あなたのパソコンはもちろん、FAXや携帯電話などの機械全般をさしています。
どんなプログラム言語を使って作ったものでも、最後は機械語に翻訳されます。
つまり、今までと同様に、この先もどれだけ沢山のプログラム言語が生まれようと、最終的には機械語に変換され実行されていきます。
そしてその機械語というのは、動作環境つまり、機械ごとに少しずつ異なっています。
正確に言うと基本的なところは同じなのですが、目に見える段階になってくる頃には、大きく違ってくるといった方がよいでしょうか…。
ちょうど、パソコンとFAXではできることが違うのと同じです。
パソコンひとつとっても、WindowsとMacintoshでは動作環境が違うのと同じです。
なんとなくずれてきたような気がしますが、イメージ的にはこんな感じです。
ここまではいいですよね。
次は、その機械語にするまでのプロセスについての話をします。
この機械語にするまでの手段つまり、プロセスの違いというのが、各プログラミング言語の違いにあたります。
ではどう違うのかについてお話します。
まず機械語というのは、すべてが1と0で表現された数字の羅列です。
機械というのは電化製品ですから、電気が通っている状態と通っていない状態を表現するのに、ちょうど1と0がわかりやすいわけです。
そして、すべてが2種類の文字で表現されていることから、2進数で解釈されます。
2進数とは、すべてが1と0で表現され、数値が2まで上がったら桁上がりをする数のことです。
ちなみに、人間が普段使っているのは10進数です。
では、このような機械語を人間が解釈しようと思ったら、1と0の羅列とひたすらにらめっこすることになりますよね。
ちょうど、映画マトリックスにも、1と0のコードを処理している場面がありましたが、あんな感じです。
でも、あんなことなかなかできませんよね。
というかイヤですよね。
めんどくさそうだし(苦笑)。
ということで登場したのがアセンブラという言語です。
アセンブラ言語はアセンブリ言語とも呼ばれ、機械語の命令とプログラムコードの命令とを、1対1で対応させたシンプルなプログラミング言語です。
そのため、プログラミング言語としての水準は低いですが、マシンの動きを理解するには最適な言語です。
しかし、このアセンブラ言語で少し複雑なことをしようと思ったら、本当に複雑になってしまって、なかなか手におえるものではなくなってしまいます。
そこで、次に登場したのがC言語です。
C言語は、人間がなるべく理解しやすいようなプログラムコードで作成できるよう工夫された高級言語の代表格です。
このC言語というのは、今ではいろいろなプログラミング言語のコーディング方法の基礎となっています。
今学習しているPerlプログラムというのも、C言語のコーディング方法と似ているところが多いです。
C言語のおかげで、各分野でのプログラム開発はかなり進歩しました。
しかし、C言語はプログラムコードを作成した後、コンパイラと呼ばれる端末専用のソフトウェアを使って、実行形式のプログラムファイルを作成する必要がありました。
この実行形式のファイルというのが、機械語で書かれた命令文にあたります。
C言語はこのような性質を持っていたため、コンパイラ言語とも呼ばれ普及はしましたが、それはコンパイラを持っている人だけにとどまりました。
それでは困るので、プログラミング方法はC言語並みの高級言語を維持したまま、もっと気軽にプログラムとして実行させる方法はないものか…。
このようなニーズにこたえる形で誕生したのが、CGIの代表的存在のPerlプログラムです。
やっとPerlが出てきましたね。
ここまで長かったですね(苦笑)。
Perlプログラムはすでにおわかりの通り、プログラムコードのまま実行させることができます。
以前書きましたが、Perlパッケージがプログラムコードが書かれたファイル実行時に、その場で機械語に翻訳しているからですね。
このようなプログラム実行システムをとっている言語のことを、インタプリタ言語といいます。
インタプリタ言語は、プログラムコードが書かれたファイルつまり、ソースファイルのままで動かすことができることから、現在幅広く利用されています。
やはり実行形式のファイルが、プログラムコードのままになっているということは、プログラムコードそのものに触れる機会が増えますから…。
当然、そこから自分でもプログラムを作成してみようと思った人が増えたのでしょうね。
さらに、プログラム言語は利用形態に合わせて、どんどん新しいシステムが作られていきます。
今ではインターネットがどんどん普及し、パソコン以外の端末もインターネットにつながるようになりました。
異なるルールをもった端末同士が、インターネットという大きな接続ルールに従っているわけです。
こうなってくると次は、インターネットをもっと便利に使うため、いろいろな端末上で動かせる共通のプログラミング言語というのがほしくなるわけです。
しかし、インターネットにつながっているルールは共通のものでも、それぞれの端末は独自のルールを採用しています。
この悩みを解決し誕生したのが、javaに代表される中間形式言語とよばれるプログラミング言語です。
中間形式言語は、どのような実行プロセスを経ているのかというと…。
まず、隔たりをなくすには各端末が採用している独自のルールを突破する必要がありますよね。
そのため中間形式言語では、プログラムコードから実行ファイルを作成するプロセスを、2段階に分けています。
どういうことかというと…。
まずは、プログラムコードの書かれたファイルから、仮の実行ファイルを作ります。
次に、その仮実行形式ファイルを、各端末の仮想マシン(Virtual Machine)という名のプログラムが、機械語に翻訳しながら実行させていくというプロセスです。
実行されるまでのプロセスが大きく2段階に分かれているため、一見ややこしそうですが、これならどの端末でも実行できますよね。
とにかくこれで3種類のプログラミング言語が出そろいました。
プログラム実行時のみにフォーカスすれば…。
即実行されるコンパイラ言語。
仮の実行形式から、実際の実行データを生成し実行する中間形式言語。
プログラムコードの書かれたファイルから、実行データを生成し実行するインタプリタ言語。
そして今あなたが学習しているPerl/CGIは、インタプリタ言語に属するわけです。
これで、プログラムという漠然とした世界観の中で、今学習しているPerl/CGIプログラムの位置関係が理解できたかと思います。
それでは、今回のPerl/CGIプログラム学習に移りましょう。
関数ライブラリとは?
関数ライブラリとは、 Perl/CGIプログラミング 作業をもっと便利に行うための手法のひとつです。
以前 サブルーチンについて学習 しましたよね。
今回学習する関数ライブラリとは、そのサブルーチンの使い方に応用を加えて、もっと使いやすくするような手法です。
サブルーチンの特徴のひとつに、プログラムコードの再利用が可能というのがありましたよね。
あるPerl/CGIプログラムのサブルーチン部分をコピーして、別のPerl/CGIプログラムに貼り付けて利用するといったことです。
今回学習する関数ライブラリは、そのサブルーチン部分というのが、ファイルの一部ではなく、ひとつのファイル全体になったものです。
つまり、サブルーチン単位の場合は、プログラムファイルの一部をコピーペーストしていたものが…。
関数ライブラリでは、それがファイル単位になったというわけです。
プログラムを再利用するにしても、ファイルの一部をコピーペーストして作っていくよりも、ファイル単位で作っていった方がらくですよね。
それに、さまざまなケースで使用する定番処理部分をサブルーチン化しておき、それらを関数ライブラリにしてファイル単位で管理しておけば、わかりやすくなります。
ようするに、プログラミングの効率化が期待できるわけです。
今回は、そんな関数ライブラリを利用して、Perl/CGIプログラムを作成していく方法について学習していくわけですね。
関数ライブラリの使い方
Perl/CGIプログラミングで関数ライブラリを使用する方法についてみていきましょう。
関数ライブラリはファイルごとに管理していくので、今回は呼び出される側の関数ライブラリ側のファイルと、それを呼び出すメイン部分のファイルの2種類を作成します。
関数ライブラリファイルの作成
まずは、関数ライブラリ側のファイルを作成します。
このファイルは、メイン処理から呼び出されて実行されるサブルーチンを集めたファイルになります。
ですから、基本的なプログラミング方法は変わりません。
しかし、関数ライブラリとして使用するための宣言と、プログラムファイルの一部として利用できる手続きを宣言する必要があります。
具体的には、1行目にはパッケージ名を、そのファイルの末尾には「1」を記述することです。
例えばこんな感じです。
package test;
use strict;
sub routine1 {
my @number = @_;
my $x = 0;
for(my $i=0 ; $i<=$#number ; $i++) {
$x += $number[$i];
}
return $x;
}
1;
1行目の「package test;」で、パッケージ名を宣言しています。
このファイルのパッケージ名が「test」であるという意味です。
パッケージ名に使用できる文字は、 変数名 やサブルーチン名と同じです。
パッケージ名は基本的に自由につけることができますが、ひとつのPerl/CGIプログラム内で、複数のパッケージ名が重複しないようにする必要があります。
ファイルの末尾には、「1;」を書きます。
以上のことを守ってさえいれば、今まで学習してきたことを生かしてPerl/CGIプログラムを作成することができます。
「use strict;」を使って、局所化されていない変数をチェックする こともできますし…。
サブルーチンの引数や戻り値も普通に使えます。
このパッケージ名「test」のファイル名は、「test.pl」としてテキスト形式で保存します。
パッケージ名とファイル名を無理に一致させる必要はないですが、同じ方が後々便利です。
Perl/CGIプログラム本体は「.cgi」、今回のような関数ライブラリの場合は「.pl」とするのが一般的です。
これで、メイン処理から呼び出される関数ライブラリのファイル「test.pl」が完成しました。
メイン処理ファイルの作成
次に、Perl/CGIプログラムのメイン処理部分のファイルを作成します。
メイン処理のファイルから、外部ファイルの関数ライブラリを呼び出して使用するためには…。
まずは下準備として、外部の関数ライブラリファイルまでのパスを指定して、プログラムを読み込むインクルードというコーディングをします。
そして実際に外部ファイルの関数ライブラリのサブルーチンを呼び出すには、頭にサブルーチンを指定する「&」を付けて、その後にパッケージ名とサブルーチン名を記述していきます。
パッケージ名とサブルーチン名の間には、「::」をはさみます。
#!/usr/bin/perl
use strict;
require './test.pl';
my $answer = &test::routine1(7, 15);
print "Content-type: text/html\n\n";
print $answer;
exit;
これを、「test.cgi」という名前で保存します。
「require './test.pl';」という部分で、外部の関数ライブラリファイル「test.pl」を読み込んでいます。
require関数はこのように、外部の関数ライブラリを読み込むことができます。
「./」は、メイン処理のファイルから見た「test.pl」までの 相対パス です。
つまり、「test.cgi」と「test.pl」は、同じ階層にあることを表しています。
ちょうど、「test.cgi」のよこに「test.pl」が並んでいる感じです。
このような場合であれば、「./」は省略してもかまいません。
これで、外部ファイルの関数ライブラリを使用する下準備が整いました。
次は実際に、プログラムを呼び出して使います。
関数ライブラリにあるサブルーチンを呼び出している部分は「my $answer = &test::routine1(7, 15);」ですよね。
「&test::routine1」とは、パッケージ名「test」に所属するサブルーチン名「routine1」を呼び出す指定になります。
サブルーチン名の呼び出しである「&」が頭についていたり、パッケージ名とそこに属するサブルーチン名との間に「::」などが付いていますが、引数や戻り値などは普通に使えます。
ちなみにここで使用しているサブルーチンは、複数の引数の値を合計し戻り値として返すプログラムです。
以前使用したので、あえて細かい解説はしません。
Perl/CGIプログラムの実行
今まで通り、インターネットサーバーにアップロードして実行しますが、パーミッションつまり、実行権は、メインのPerl/CGIプログラムファイルにのみ与えます。
ようするに、「test.cgi」にのみ、「755」や「701」といった実行権を与えます。
「test.pl」はアップロードするだけで、パーミッションを変更する必要はありません。
まぁ、両方とも実行権を与えても問題ないのですが…。
仮に「test.pl」に実行権を与えても、このファイル単体では動作しないので無駄ですね。
アップロードとパーミッションの設定ができたら、「test.cgi」にアクセスして実行してみてください。
このPerl/CGIプログラムを実行すると、「22」と表示されます。
これで今回の学習テーマ、「関数ライブラリの使い方」については以上です。
分量が少し少ないですが、まぁちょうどきりがいいので、今回はここで終了です。
編集後記
今回は、編集前記の続きで…。
コンパイラ言語。
中間形式言語。
インタプリタ言語。
いまいち覚えにくいこの3種類のプログラミング言語について、例をあげつつそれぞれの違いについてもう少しお話しします。
今学習しているPerl/CGIプログラムはインタプリタ言語に属することはわかりましたが、「だから何?」といった感じですよね。
だから、ほかの言語と比べつつ、それぞれの特徴をばっちりつかんでしまおうというのが今回のお話です。
ここからは、あなたのイメージ力をフルに使って読んでくださいね。
例えば、コンパイラ君、中間君とインタプリタ君の3人で、カニを食べに行ったとします。
この3人は普段は仲が良いのですが、みんなカニの食べ方に対してはそれぞれのこだわりを持っていたため、3人ともお店では別のテーブルに着きました。
ここで、「それじゃあ一緒に食べに行く意味ないじゃん」という突っ込みは無視します(苦笑)。
それぞれのテーブルから、3人同時に注文をしました。
まず一番最初にカニが運ばれてきたのは、インタプリタ君です。
すぐにカニが運ばれてくるかわりに、インタプリタ君のカニは、殻がついたままになっています。
さすがにからごとは食べられないので、ハサミやスプーンなどの道具も付いています。
インタプリタ君は、ハサミで殻を割り、スプーンで中身を取り出しながら食べ始めました。
しばらくして次にカニが運ばれてきたのは、中間君です。
中間君のカニにも同じように殻がついていましたが、手で割りやすいように切れ目が入れてありました。
ですから道具も、中身を取るためのスプーンのみです。
中間君は、簡単に殻を割って、スプーンを使って食べ始めました。
さらに時間が経過し、最後にカニが運ばれてきたのは、コンパイラ君ですね。
ですが、コンパイラ君のカニには、ひとつも殻は乗っていません。
道具といえばはしぐらいです。
殻はすでにわってあったのです。
コンパイラ君は、運ばれてきたカニをパクパク食べ始めました。
以上です。
ひとりずつ、食べ方を細かく注文するなんて、なんてわがままな客だと思ったかもしれませんが…。
まぁそのへんはおいておいてください(苦笑)。
この3人のカニの食べ方こそが、各プログラムの実行の様子を表しているのです。
さらに、この3人にカニ料理を出す調理段階というのが、ちょうどプログラム作成作業にあたります。
どういうことかというと…。
Perlに代表されるインタプリタ言語は、プログラムコードのまま実行させることができましたよね。
つまり、お客さんが自分で殻をむいて食べるので、カニを殻ごと出しているのと同じです。
したがって、調理にかかる手間は少なくて済みますが、カニと一緒に、ハサミやスプーンなどを出してあげなくてはいけないわけです。
その結果、完成した料理をのせるおぼんはかさばってしまいます。
これは、Perlプログラムを動かすには、必ずPerlパッケージを必要とすることと同じです。
つまり、1行目に書かれているPerlのパスが必須であるということです。
さらに、カニが殻ごと出されたということは、自分でハサミを入れて殻を割り、スプーンで中身をすくってからでないと口に運べないということですよね。
ひとつ口に入れてから、次を口に入れるまで、多少なりとも時間がかかるということになります。
これは、プログラムコードのまま実行させなくてはいけないことから…。
Perlパッケージが、プログラムコードの内容を解釈しながら、機械語に翻訳しつつパソコンの頭脳とも言うべきCPUが実行していくのと同じです。
次は、中間形式言語についてです。
中間形式言語は、一度仮の実行形式データを作ってから、もう一度そこから本当の実行形式のデータを作成していくのでしたね。
これは、調理段階であらかじめカニの殻にハサミを入れて割りやすい状態を作っておき、そして食べる段階では、殻をむきながら食べていくといった感じですよね。
中間形式言語もまずは、プログラムコードを解釈し、仮の実行形式データを作っておきます。
そして実際に実行するときには、仮の実行形式データから、各実行環境に合わせて実行データを作成しながら走らせていきます。
程度は違えど中間形式言語もインタプリタ言語のように、機械語に翻訳しながら実行していきます。
しかし、すでに仮ではありますが実行形式のデータを作成していた中間形式言語のほうが、食べ始めれば(実行し始めれば)早いわけです。
ただ殻を割って食べるにしても、あらかじめ殻が割れやすくなっているので、簡単に食べられるのと同じですね。
個人的にはこの食べ方が好きですね(笑)。
最後は、コンパイラ言語です。
コンパイラ言語は、すでに機械語に翻訳済みの実行データが作成されていますから、あとは実行するだけです。
つまり、すでに殻を割り、中身を取り出してあるので、あとは食べるだけなわけです。
食べ始めてしまえば(実行し始めてしまえば)この中では一番早いです。
しかしコンパイラ言語は、あらかじめプログラムコードをコンパイラというソフトウェアを使って、実行データにしておく必要があります。
調理場では、カニの殻を割り、中身を取り出しておかなくてはいけないのと同じです。
ようするに、最速であることと引き換えに下準備に時間がかかるというわけですね。
でも、そのおかげでおぼんは軽くなり、食べるのも次々口に運ぶことができます。
コンパイラで作成した実行データは、機械語で書かれたデータですから、あとはひたすら実行すればよいわけです。
それに、機械語に翻訳されたデータですから、人間向けの情報は削られ、データサイズも軽くなっています。
実際、実行速度はインタプリタ言語よりも、コンパイラ言語のほうが早いです。
まぁ、実行条件によっては変わってくるかもしれませんが、とにかく速さを求めるのであれば、コンパイラ言語を使うのがよいでしょうね。
今回の学習は以上です。
ありがとうございました。
<戻る>