Perlでは外部モジュールを利用するのにCPANを利用します。モジュールのインストールで管理者権限が必要ならばlocal::libを利用すれば、管理者権限が必要ない場所にモジュールをインストールすることもできます。
また、この記事で利用しているPerlのバージョンはv5.32.1になります。
目次
CPANからモジュールをインストール
CPANを利用するときに必要な外部ツールとして以下のものが必要になる場合があります。
- make
- gcc
- g++
- unzip
- curl / wget / ftp
makeは必要になるため、あらかじめインストールしておく必要があります。
また、CPANのモジュールがC言語で書かれているものもあるため、C言語のコンパイラもあらかじめインストールしておく必要があります。
unzipやcurl等のツールは有名なLinuxディストリビューションでは基本的に標準で入っている場合が多いですが、環境にない場合はインストールしておきましょう。
まず始めに、CPANからのモジュールのインストールで管理者権限が必要がなくなるようにlocal::libを利用したCPANのモジュールインストール方法を記述します。
これは、CPANからのダウンロード自体には管理者権限は必要ありませんが、パッケージのインストール先のディレクトリに管理者権限が必要なディレクトリへのインストールを行う場合があります。なので、local::libを用いて、このインストール先のディレクトリを変更し、変更したディレクトリからPerlでモジュールが利用できるような環境変数の生成を実行します。
この実行を~/.bash_profileや~/.bashrcに書き込んで設定完了になります。
local::lib自体のインストールにCPANを利用できない(ダウンロードではCPANを利用します)都合上、自分でmakeを用いて、インストールする手間はありますが、モジュールのインストールを管理者権限なしで利用できる利点を考えると最初にやっておいて損はないと思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$ cpan -g local::lib # -gオプションでパッケージのみをカレントディレクトリにダウンロード $ ls local-lib-2.000024.tar.gz $ tar xf local-lib-2.000024.tar.gz # ファイルの解凍 $ cd local-lib-2.000024/ $ perl Makefile.PL --bootstrap # デフォルトのインストール先が~/perl5になります。 $ # perl Makefile.PL --bootstrap=~/foo # こっちは違うディレクトリにしたい場合に利用 $ make test && make install $ perl -I$HOME/perl5/lib/perl5 -Mlocal::lib # local::libを利用すると例えば以下のような環境変数が生成されます PATH="/home/ubuntu/perl5/bin${PATH:+:${PATH}}"; export PATH; PERL5LIB="/home/ubuntu/perl5/lib/perl5${PERL5LIB:+:${PERL5LIB}}"; export PERL5LIB; PERL_LOCAL_LIB_ROOT="/home/ubuntu/perl5${PERL_LOCAL_LIB_ROOT:+:${PERL_LOCAL_LIB_ROOT}}"; export PERL_LOCAL_LIB_ROOT; PERL_MB_OPT="--install_base \"/home/ubuntu/perl5\""; export PERL_MB_OPT; PERL_MM_OPT="INSTALL_BASE=/home/ubuntu/perl5"; export PERL_MM_OPT; $ echo 'eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)' >> ~/.bashrc # シェルの起動スクリプトに書き込む $ source ~/.bashrc # 環境変数を設定するために起動スクリプトをリロードします |
おすすめのモジュールとしてApp::cpanminusがおすすめで、cpanmコマンドが利用でき、モジュールのインストール等がcpanに比べより便利になります。
1 |
$ cpan App::cpanminus |
App::cpanminusをインストールするとcpanmコマンドで利用できるようになり、以下のようなコマンドでcpanコマンドの代わりにモジュールをインストールできます。
1 |
$ cpanm <module_name> |
モジュールの利用(ライブラリの利用・ライブラリ検索パス)
Perlモジュールを利用する場合、ファイル拡張子は.pmになります。
ライブラリの検索パスは環境変数PERL5LIBを利用します。環境変数PERL5LIBがない場合は環境変数PERLLIBが利用されます。
プログラム中に検索パスを入れる場合はuse lib文を利用できます。
1 |
use lib libdirname |
モジュールは基本的にuse文を利用しインポートして使用します。
1 2 3 |
use Modulename; use Modulename LIST; #LISTはインポートしたいもののリスト use Modulename (); |
これらの文はそれぞれ以下の文と等価になります。
1 2 3 |
BEGIN { require 'Modulename.pm'; 'Modulename'->import; } BEGIN { require 'Modulename.pm'; 'Modulename'->import( LIST ); } BEGIN { require 'Modulename.pm'; } |
ライブラリを利用するときは、use文はBEGIN文に置き換わるので、require文よりuse文の方が推奨されます。
オブジェクト指向プログラミング
perlでオブジェクト指向プログラミングを行う場合は、クラスとしてパッケージを利用します。
さらにオブジェクトのリファレンスを得るためにbless関数を利用します。
1 |
bless REF, CLASSNAME |
bless関数はリファレンスとクラスの名前(パッケージの名前)を関連付けます。
REFはリファレンスで、CLASSNAMEは文字列になります。
返却値は便宜上のためにREFが返されます。
つまり、perlでのオブジェクト指向プログラミングは以下のようになります。
main.pl
1 2 3 4 |
use ExampleClass; my $obj = ExampleClass->new; $obj->print; |
ExampleClass.pm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package ExampleClass; use feature 'say'; my $data = 'ExampleClass Message'; sub new { $classname = shift; $self = {}; bless $self, $classname; return $self; } sub print { $self = shift; say "$data"; } 1; |
実行結果
1 2 3 4 |
$ ls ExampleClass.pm main.pl $ perl -I. main.pl ExampleClass Message |
ExampleClass.pmについて、コンストラクタのnew関数では、$classnameは文字列の'ExampleClass'が取得できます。これは、
1 |
ExampleClass->new |
で、new関数の引数が
1 |
new ExampleClass, ... |
のように渡されるからです。ここで第1引数のExampleClassはベアワードで解釈としては文字列になります。
new関数内のその次の処理はbless関数のために空のハッシュリファレンスを作成して、空のハッシュのリファレンスとクラスを関連付けています。最後にそのリファレンスを返却しています。
ExampleClass.pmについて、メソッドのprint関数のshift関数で渡されるものについて、まず、例えば、main.plでは
1 |
$obj->print |
のように呼び出されています。print関数の引数は
1 |
print $obj, ... |
のように渡されます。第1引数の$objはリファレンスで、そのオブジェクト自身のリファレンスになります。
ここでは、そのリファレンスを活用していませんが、引数から受け取ったリファレンスを利用することでオブジェクトデータの操作ができます。
また、ExampleClass.pmの最後の'1;'の行の意味はtrue(真)の値を返す意味になります。これはモジュールは最後にtrueの値を返す必要があるという約束事みたいなものになります。
これだけではオブジェクト指向プログラミングとしては、かなり不完全なものとなります。例えば、上の説明では継承やアクセス権等がありません。また、Perlのオブジェクト指向プログラミングを実現するための便利モジュールとして、ドキュメントでは、MooseモジュールやMooモジュールが紹介されています。
補足として、実行の際に使用したperlのコマンドラインオプションのIオプションでライブラリの検索パスを追加できます。検索パスの追加方法としてmain.plのインポート方法を
1 2 |
use lib '.'; use ExampleClass; |
のように修正して実行する方法もあります。
モジュールの利用(自作モジュールの作成)
かなり簡略化した形で自作モジュールで作成したいと思います。手探りで試してみたものなので間違っている点があるかもしれませんがご了承ください。
ここでは、perlに付属されているh2xsというツールを使って、モジュールのひな形を作り、プログラムを記述し、簡単なテストコードを書いて、インストールを行って、Perlのコマンドラインでモジュールを呼び出したいと思います。
つまり、ここでのモジュール作成の目標は以下のように呼び出せるようにしてみることになります。
1 2 |
$ perl -MMylib::Mymod Hello World |
始めに、h2xsコマンドを用いて、モジュールのひな形を作成します。
1 |
$ h2xs -AX --skip-exporter --use-new-tests -n Mylib::Mymod |
-nオプションでモジュールの名前を指定します。
このコマンドを実行したら、以下のように実行され、カレントディレクトリにモジュールのひな形が作られます。
1 2 3 4 5 6 7 8 9 10 11 |
$ h2xs -AX --skip-exporter --use-new-tests -n Mylib::Mymod Defaulting to backwards compatibility with perl 5.32.1 If you intend this module to be compatible with earlier perl versions, please specify a minimum perl version with the -b option. Writing Mylib-Mymod/lib/Mylib/Mymod.pm Writing Mylib-Mymod/Makefile.PL Writing Mylib-Mymod/README Writing Mylib-Mymod/t/Mylib-Mymod.t Writing Mylib-Mymod/Changes Writing Mylib-Mymod/MANIFEST |
次に作成されたディレクトリに移動します。
1 |
$ cd Mylib-Mymod/ |
作成されたディレクトリにあるlib/がプログラムを記述するソースコードがある場所になります。
lib/Mylib/Mymod.pmの'1;'の行の上に以下の行を追記します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
my $data = "Hello World"; sub new { my $class = shift; bless {}, $class; } sub import { my ($class, @args) = @_; my $self = $class->new; if ($0 eq '-') { print $self->getdata,"\n"; exit 0; } } sub getdata { return $data; } |
'1;'はモジュールの終わりにtrue(真)の値を返す約束事になります。
また、=head1等があるかもしれませんが、これはPerlのPOD(Plain Old Document)というもので、ドキュメント作成に利用されるPerl用のマークアップ言語になります。
use文が用いられると自動的にimport関数が呼び出されます。$0は実行したプログラム名が入りますが、コマンドラインで実行するときにモジュールのみをインポートし引数を渡さなかった場合は'-'になります。
t/はテストファイルを置くディレクトリになります。ここではdata_check.tとして新しくテストファイルを作成します。
ここでのテストは簡単にテキストデータが意図したものかを確認してみるとします。
t/data_check.t
1 2 3 4 5 6 7 8 |
use strict; use warnings; use Mylib::Mymod; use Test::More tests => 1; my $mymod = Mylib::Mymod->new; ok($mymod->getdata eq 'Hello World', 'Data check test'); |
ソースコードとテストコードが書き終わったら、makeを行います。ドキュメントなども作成したほうが良いかもしれませんがここでは省略します。
makeの手順は
1 2 3 4 |
perl Makefile.PL make make test make install |
になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ ls Changes MANIFEST Makefile.PL README lib t $ perl Makefile.PL ~~~~省略~~~~ $ make ~~~~省略~~~~ $ make test PERL_DL_NONLAZY=1 "/usr/bin/perl" "-MExtUtils::Command::MM" "-MTest::Harness" "-e" "undef *Test::Harness::Switches; test_harness(0, 'blib/lib', 'blib/arch')" t/*.t t/data_check.t ... ok t/Mylib-Mymod.t .. ok All tests successful. Files=2, Tests=2, 0 wallclock secs ( 0.04 usr 0.00 sys + 0.19 cusr 0.03 csys = 0.26 CPU) Result: PASS $ make install ~~~~省略~~~~ |
make testで失敗したら、ソースコードまたはテストコードを書き直して、再びmake testを行います。
また、make install時にlocal::libの設定を行っていない場合は、管理者権限が必要なディレクトリにインストールすることになり、sudo make installのようにしなければいけないかもしれません。
うまくインストールされたらコマンドラインで実行してみて、正しく実行されたら終了となります。
1 2 |
$ perl -MMylib::Mymod Hello World |
プラグマ
Perlの機能を細かく制御したい場合は、'use'のキーワードを用いてプラグマを利用します。逆に利用したくない場合は'no'のキーワードを用います。
プラグマの効果はブロックの終わりまで続きます。
よく利用されるものとして、strictやwarnings等があります。
strictはデバッグが行いにくい表現を制限するプラグマになります。strictの宣言は以下のものがあります。
1 2 3 4 |
use strict; use strict 'vars'; use strict 'refs'; use strict 'subs'; |
'use strict'の場合は、"vars", "refs", "subs"のすべての効果を持つ宣言になります。
それぞれ制限されエラーになる表現は
vars: 明示的に宣言されていない変数の利用時に実行時エラー
refs: シンボリック参照の利用時に実行時エラー
subs: 関数なのか文字列なのかがあいまいになるベアワードの利用時に実行時エラー
になります。
例えば、それぞれのエラーが出る場合は以下のようなものになります。
use strict 'vars'の場合
1 2 3 4 |
$ perl -e 'print $nousevar' $ perl -e 'use strict "vars"; print $nousevar' Global symbol "$nousevar" requires explicit package name (did you forget to declare "my $nousevar"?) at -e line 1. Execution of -e aborted due to compilation errors. |
use strict 'refs'の場合
1 2 3 4 |
$ perl -e '$var = "aaa"; $ref = "var"; print "$$ref\n"' aaa $ perl -e 'use strict "refs"; $var = "aaa"; $ref = "var"; print "$$ref\n"' Can't use string ("var") as a SCALAR ref while "strict refs" in use at -e line 1. |
use strict 'subs'の場合
1 2 3 4 5 |
$ perl -e '$var = aaa; print "$var\n"' aaa $ perl -e 'use strict "subs"; $var = aaa; print "$var\n"' Bareword "aaa" not allowed while "strict subs" in use at -e line 1. Execution of -e aborted due to compilation errors. |
warningsはオプションになっている注意を表示できるプラグマになります。また、warningsのカテゴリは多くあるので詳しくは公式ドキュメントを参照してください。
例えば、注意は以下のような文で表示できます。
1 2 3 |
$ perl -e 'use warnings; "aaa"; print "hello\n"' Useless use of a constant ("aaa") in void context at -e line 1. hello |
'use feature'のプラグマは新しい機能を有効にするプラグマになります。既存のプログラムに対して、新しい機能へのリスクを抑えることができるプラグマになります。
例えば、
1 |
use feature 'say'; |
とすると、改行を入れてくれるprint文としてsay関数が利用可能になります。他にも
1 |
use feature ':5.10'; |
とし、Perlのバージョンの5.10の機能を設定することもできます。
'use VERSION'のプラグマの
1 |
use v5.10.0; |
は、
1 2 |
no feature ':all'; use feature ':5.10'; |
を暗黙的に行います。
参考
perlの公式サイト
The Perl Programming Language - www.perl.org
CPANの公式サイト
The Comprehensive Perl Archive Network - www.cpan.org
metacpan - CPANモジュールの検索サイト
Search the CPAN - metacpan.org
perlのドキュメントを日本語に翻訳しているサイト
perldoc.jp
Perlのオブジェクト指向プログラミングについてのより詳しい説明はPerlのドキュメントの
perlootut - Object-Oriented Programming in Perl Tutorial - Perldoc Browser
perlobj - Perl object reference - Perldoc Browser
warningについて(カテゴリ等も書かれています)
warnings - Perl pragma to control optional warnings
perlのモジュールについて(プラグマについてはPragmatic Moduleを参考)
更にモジュールの詳しい情報を調べたい場合は、公式ドキュメントのページ内検索を用いるとよいでしょう。
perlmodlib - constructing new Perl modules and finding existing ones