Perl 言語の機能を有効にして必要なバージョンを宣言する
use
には、引数に指定したモジュールをロードする機能と、
Perl 本体のバージョン番号を指定して該当の Perl プログラムがそれより以前のバージョンで動作しないようにする機能の
2 つの役割があります。
use
は、Perl モジュールから現在のパッケージにインポートします。
これは内部的には次のコードとまったく同じです。
BEGIN { require Module; Module->import( LIST ); }
BEGIN
によって、コンパイル時に require
と
import
が実行されます。
require
は、もしまだ該当のモジュールがメモリーにロードされていなければ、
それをロードします。
import
は組み込み関数ではなく、モジュール側の通常の静的なメソッドに過ぎません。
このメソッドは、指定された機能のリストを現在のパッケージにインポートするとモジュールに伝えます。
import
メソッドの実装について決まりはありませんが、
ほとんどのモジュールは Exporter
モジュールの中で定義された Exporter
クラスからの継承を経由して
import
メソッドを派生させることを選んでいるだけです。
もし import
メソッドが見つからなければ、
AUTOLOAD があったとしても、その呼び出しはスキップされます。
パッケージの import
を呼び出したくない場合
(たとえば、あなたの名前空間を選択されないようにするなどの理由で) は、
明示的に空のリストを指定します。
use Module ();
これは次のコードと同じです。
BEGIN { require Module }
この件について少し具体例を見てみましょう。次の例は、
標準モジュール File::Copy を使って、
テキストファイルをコピーしています。
File::Copy はデフォルトでは copy
という関数名を呼び出し元のスクリプトの名前空間に組み込みます。
これによって、本来は別のパッケージで合った File::Copy の関数を、
あたかも呼び出し元で定義されたかのように使うことができます。
use File::Copy;
copy( './orig.txt', './copy.txt' );
一方で、このように名前空間をモジュールが勝手に使ってしまうと問題も起こります。
もしあなた自身で copy
という名前のサブルーチンを定義しようとすると、
名前がバッティングしてしまうからです。
File::Copy に自身の名前空間を汚させないようにするには、use
で File::Copy をロードする際に、空のリストを与えます。
こうすることで、File::Copy の copy
関数は、File::Copy
という名前空間を前置しないと利用できなくなります。
use File::Copy ();
File::Copy::copy( './orig.txt', './copy.txt' ); # 動作する
copy( './orig.txt', './copy.txt' ); # エラーになる
もし引数 VERSION が Module と LIST の間に存在したら、
use
は Module クラスの中にある VERSION
メソッドを呼び出します。
その際に、引数に指定されたバージョンを引数として引き渡します。
use Module 12.34;
これは次のコードと同じです。
BEGIN { require Module; Module->VERSION(12.34) }
デフォルトの
VERSION
メソッドは、
UNIVERSAL クラスから継承されたものですが、
もし指定のバージョンが変数 $Module::VERSION
の値より大きい場合は croak します。
引数 VERSION はどんな表現でも許されているわけではありません。
数値、または、v
の後ろに数値が続く形式のバージョン番号リテラルの場合のみ
VERSION として認められます。
バージョンリテラルのように見えないものは LIST の最初の要素として解釈されます。
とはいえ、どんな表現を引数 VERSION に使ったとしても、あたかも機能したかのように見えるでしょう。
なぜなら、Exporter
の import
メソッドは、数値の引数を特別に扱うからです。
エクスポート対象として扱うのではなく、バージョンチェックを実行します。
もう一度言いますが、LIST の省略(import
は引数なしで呼び出されます)と、
明示的な空の LIST ()
(import
は呼び出されません)は、同じではありません。
また、VERSION の後ろにカンマを入れないでください。
use
はワイドオープンインタフェースのため、プラグマ(コンパイラディレクティブ)も
use
を使うように実装されています。
例を挙げると、現在、次のようなプラグマが実装されています。
use constant;
use diagnostics;
use integer;
use sigtrap qw(SEGV BUS);
use strict qw(subs vars refs);
use subs qw(afunc blurfl);
use warnings qw(all);
use sort qw(stable);
これらの疑似モジュールのいくつかは、
strict
や
integer
のように、現在のブロックスコープの中にセマンティクスをインポートします。
通常のモジュールなら、現在のパッケージにシンボルをインポートし、それはファイルの最後まで有効となりますので、
その点が異なります。
use
はコンパイル時に有効になるため、
コンパイル対象のコードに通常のフロー制御があっても機能しません。
たとえば、条件の偽の分岐の中に use
を置いても、処理を回避することはできません。
条件付きでモジュールやプラグマをロードしたいなら、if
プラグマを使ってください。
use if $] < 5.008, "utf8";
use if WANT_WARNINGS, warnings => qw(all);
use
によってインポートするのとは逆に、インポートしないと命令する no
宣言があります。
つまり、import
の代わりに Module->unimport(LIST)
を呼び出します。
それは、VERSION を付け、LIST を省略する、または、空の LIST を指定した
import
、または、unimport
メソッドが見つからなかったかのように振る舞います。
no integer;
no strict 'refs';
no warnings;
標準モジュールとプラグマのリストは perlmodlib
を参照してください。
コマンドラインからでも Perl コマンドラインオプション -M
や -m
を使うと
use
機能が使えますが、その詳細については perlrun を参照してください。
この構文は、リクエストされた Perl バージョンで利用可能なすべての機能を有効にします。 ただし、リクエストされたバージョンの機能バンドルの中にはない機能はすべて無効にします。 どの機能が有効になるのかは feature プラグマによって定義されていますので、そちらを参照してください。
VERSION には v5.24.1 のような v-string を指定することができます。
これは、$^V ($PERL_VERSION) の結果に相当します。
または、5.024001 のような形式の数値で指定することもできます。
これは $] の結果に相当します。
もし VERSION が現在の Perl インタプリタのバージョンより大きい場合は例外が投げられます。
Perl はファイルの残りを解析することもしません。
require
もコンパイル時に類似のチェックを行います。
指定された Perl のバージョンが 5.12 以上なら、use strict
が指定されたのと同様に strict モードが有効になります。
同様に、指定された Perl のバージョンが 5.35.0 以上なら、warnings
が有効になります。
use VERSION
が指定されると、以前の use VERSION
のすべての挙動は上書きされます。つまり、後の指定が優先します。
それによって、場合によっては、strict
, warnings
, feature
が削除されるかもしれません。
use VERSION
は feature.pm
, strict.pm
,
warnings.pm
ファイルをロードしません。
5.024001 といった形式の数値を VERSION に指定するのは一般的には避けるべきです。 なぜなら、v5.24.1 と比べて、古くて読みづらい構文だからっです。 2002 年にリリースした Perl 5.8.0 より前では、もっと冗長な数値形式しか構文としてサポートされていませんでした。 そのため、次のようなコードを見たことがあるかもしれません。
use v5.24.1; # コンパイル時にバージョンをチェック
use 5.24.1; # 同上
use 5.024_001; # 同上(Perl 5.6 と互換のある古い構文)
use VERSION
は、古いバージョンでは動作しないライブラリーモジュールを use
で読み込む前に、
現在の Perl のバージョンをチェックしたい場合に役に立つでしょう。
以上とは逆に、no VERSION
を使うと、指定の Perl バージョンより古いバージョンを必要としていることを指定することもできます。
過去の経緯を言うと、これは、Raku 言語(以前は "Perl 6" と呼ばれていました)の設計の初期段階で加えられたもので、
次のように、Perl 5 のプログラムが自身は Perl 6 プログラムではないことを宣言できるようにしたものです。
no 6;
これら 2 つの言語で、実装、ファイルの命名の慣例、その他の基盤が異なるため、 この機能は今はもう実際に使われることはなく、これから作るコードでは使うべきではありません。
no VERSION
は、実行中の Perl が引数に指定されたバージョンより前のバージョンだということを
宣言するためだけに使われているにすぎません。
機能を有効にする側の use VERSION
を取り消すわけではありません。
そのため、no VERSION
を使うときは注意してください。