プログラミング > Perl > 附録

ここでは、本編でカバーされなかったPerlに関するさまざまな話題や知識をまとめています。これらの情報は必須ではないかもしれませんが、Perlをより深く理解し、効率的に活用するために役立つ内容です。


モジュール管理

編集

Perlでは、モジュール(ライブラリ)を活用することで、コードの再利用性を高め、作業を効率化できます。CPAN (Comprehensive Perl Archive Network) はPerlのモジュールを集めたオンラインリポジトリで、数千におよぶモジュールが公開されています。

CPANの利用方法

編集

CPANは簡単に利用可能です。次のコマンドでモジュールをインストールできます。

cpan install モジュール名

CPAN Minus (cpanm)

編集

CPANのフル機能を使う必要がない場合、軽量で素早いcpanmも便利です。以下の手順でインストールできます。

curl -L https://cpanmin.us | perl - --sudo App::cpanminus

その後、モジュールをインストールするには次のコマンドを使用します。

cpanm モジュール名

正規表現の高度な利用

編集

Perlは強力な正規表現エンジンを備えており、複雑なテキスト処理に最適です。ここでは、高度な正規表現のテクニックをいくつか紹介します。

捕捉グループと後方参照

編集

正規表現の捕捉グループ () を利用して、マッチした部分を後方参照することができます。

my $text = "abc123abc";
if ($text =~ /(abc)\d+\1/) {
    print "マッチしました!\n";
}

この例では、abc という文字列が前後に出現しているパターンをマッチさせています。

動的正規表現

編集

Perlでは変数を利用して動的に正規表現を生成できます。これは、柔軟なマッチング条件を必要とする場合に便利です。

my $pattern = 'foo';
my $text = 'foobar';
if ($text =~ /$pattern/) {
    print "マッチしました!\n";
}

Perlにおけるメモリ管理

編集

Perlはガベージコレクションを使用して自動的にメモリを管理しますが、メモリリークが発生する場合があります。以下のようなポイントに注意することで、メモリ効率を高めることができます。

弱参照

編集

循環参照がある場合、メモリリークが発生する可能性があります。Scalar::Util モジュールを使用して弱参照を作成し、循環参照を回避することができます。

use Scalar::Util 'weaken';

my $foo = {};
my $bar = { foo => $foo };
weaken($bar->{foo});  # 弱参照を作成

$foo = undef;  # メモリ解放

Perlと並列処理

編集

Perlには並列処理を行うためのモジュールがいくつかあります。例えば、forkを利用したプロセスの分岐や、スレッドを使ったマルチスレッドプログラミングが可能です。

forkによる並列処理

編集

次の例は、forkを使ってプロセスを並列で実行する方法を示しています。

my $pid = fork();
if ($pid) {
    # 親プロセス
    print "親プロセス (PID: $$)\n";
} elsif (defined $pid) {
    # 子プロセス
    print "子プロセス (PID: $$)\n";
} else {
    die "forkに失敗しました: $!";
}

スレッド

編集

threadsモジュールを使うことで、Perlスクリプトでスレッドを利用することができます。

use threads;

sub worker {
    my $id = shift;
    print "スレッド $id 実行中\n";
}

my @threads;
for my $i (1..5) {
    push @threads, threads->create(\&worker, $i);
}

$_->join() for @threads;

Perlと外部コマンドの連携

編集

Perlでは、外部コマンドを簡単に実行することができます。例えば、バッククォートを使うことで外部コマンドの結果を取得可能です。

my $output = `ls -l`;
print $output;

また、system関数を使えば、外部コマンドを実行してそのステータスを取得できます。

my $status = system("echo 'Hello, World!'");
print "終了ステータス: $status\n";

デバッグとプロファイリング

編集

Perlにはデバッグ用のツールや機能が多数用意されています。ここでは基本的なデバッグ方法を紹介します。

デバッガの利用

編集

Perlには組み込みのデバッガがあり、-d オプションでデバッガを起動できます。

perl -d スクリプト名.pl

デバッグプリント

編集

デバッグの際によく使われるのがData::Dumperモジュールです。データ構造の内容を人間が読める形で出力できます。

use Data::Dumper;
my $data = { foo => 'bar', baz => [1, 2, 3] };
print Dumper($data);

より高度なPerlの最適化

編集

Perlスクリプトのパフォーマンスを最適化するためのテクニックをいくつか紹介します。

メモリ効率の改善

編集

大規模なデータ処理では、メモリ効率が重要です。Tie::Fileモジュールを使うことで、大きなファイルを読み込む際のメモリ使用量を削減できます。

use Tie::File;
tie my @array, 'Tie::File', 'large_file.txt' or die $!;

正規表現のキャッシュ

編集

同じ正規表現を何度も実行する場合、正規表現オブジェクトをキャッシュすることでパフォーマンスを向上させることができます。

my $regex = qr/^\d+$/;
if ($input =~ $regex) {
    print "数字です\n";
}

機能の改廃

編集

Perlコアの機能改廃を中心にハイライトをまとめました。

Perl 5.40は、Perlプログラミング言語のメジャーリリースであり、いくつかの新機能、バグ修正、および改善が含まれています。主な変更点の概要を以下に示します。

新機能
__CLASS__ キーワード
このキーワードにより、メソッドまたはフィールド初期化子式内で現在のオブジェクトのクラス名にアクセスできます。
フィールド変数用の :reader 属性
この属性は、フィールド変数の値を返すメソッドを自動的に作成します。
コマンドラインオプション -M でスペースが許可されました
-M スイッチとモジュール名の間にスペースを含めることができるようになりました。
新しい論理XOR演算子 (^^)
Perl に排他的論理和比較のための新しい演算子が導入されました。
try/catch 機能は実験的ではなくなりました
この機能により、try と catch ブロックを使用してエラーを適切に処理できます。
複数の値を一度に反復する for
複数の値を同時に反復するために、for ループを使用できるようになりました。
組み込みモジュールは実験的ではなくなりました
組み込みモジュールとその関数は安定版と見なされます。
Term::Table および Test::Suite モジュールが追加されました
これらのモジュールは現在 Perl コアの一部であり、表形式化と包括的なユニット テスト機能を提供します。
セキュリティ
  • 2 つの脆弱性 (CVE-2023-47038 および CVE-2023-47039) が修正されました。
非互換性のある変更
reset EXPR がスカラに対して set-magic を呼び出すようになりました
この変更は、以前の動作に依存していたコードに影響を与える可能性があります。
未知のパッケージの import メソッドを呼び出すと警告が表示されます
これは、use ステートメントにおける潜在的な誤植の特定に役立ちます。
return は非直接オブジェクトを許可しなくなりました
return 演算子の構文は、非直接オブジェクトを拒否するようになりました。
no feature "bareword_filehandles" 下では、メソッド内のクラス裸ワードがファイルハンドルとして解決されなくなりました
この変更は、no feature "bareword_filehandles" ディレクティブ下でメソッド内でファイルハンドルとして裸ワードを使用していたコードに影響を与えます。
非推奨
  • 外側のスコープから内側のスコープにジャンプするために goto を使用する方法は非推奨となり、Perl 5.42 で削除されます。
パフォーマンスの向上
  • 否定演算子は、パフォーマンスを向上させるために最適化されました。
モジュールとプラグマ
  • Archive::TarattributesautodieBB::DeparseBenchmarkbignumbytesCompress::Raw::Bzip2Compress::Raw::ZlibCPAN::Meta::RequirementsData::Dumper、DB_FileDevel::PeekDevel::PPPortdiagnosticsDynaLoaderEncodeErrnoexperimentalExporterExtUtils::CBuilderExtUtils::ManifestExtUtils::MiniperlFcntlfeaturefieldsFile::CompareFile::FindFile::GlobFile::SpecFile::statFindBinGetopt::LongGetopt::StdHash::UtilHash::Util::FieldHashHTTP::TinyI18N::LanginfoIO、IO-CompressIO::Socket::IPIO::ZliblocaleMath::BigIntMath::BigInt::FastCalcMath::HugeIntMIME::LiteModule::BuildModule::CoreModule::Load::ConditionalModule::LoadedModule::SimpleModule::UtilNEXTNil::HandleOLE::DieOLE::StorageOpcodesParallel::ForkParse::CPAN::MetaPath::TinyperlPod::SimplePod::TextPod::WeaverProcInfoPS::SimpleXSXS::AutoLoaderx86_64strictTest::BuilderTest::CPANTest::DiagnosticsTest::HarnessTest::ManifestTest::MoreTest::PerlTest::PodTest::SimpleTime::HiResUnicode::CollateUnicode::NormalizeUnicode::XSUniversal::Autodievariablesversion など、いくつかのコアモジュールが新しいバージョンに更新されました。

これらの変更に加えて、Perl 5.40 には多くのバグ修正とマイナーな改善が含まれています。詳細については、Perl リリース ノート https://perldoc.perl.org/perldelta を参照してください。


Perl 5.38.0には多くの新機能と変更点があります。主な点は以下の通りです。

新機能
新しいクラス機能
クラスを定義するための新しい構文が実験的に導入されました。このfieldキーワードとmethodキーワードを使って、オブジェクトのデータとメソッドを定義できます。
Unicode 15.0のサポート
Unicode 15.0がサポートされました。
%{^HOOK}APIの導入
requireなどのキーワードの前後に実行されるフックを設定できる新しいAPIが追加されました。
PERL_RAND_SEED環境変数
この環境変数を設定することでrand関数の乱数の初期値をコントロールできるようになりました。
新しい正規表現変数${^LAST_SUCCESSFUL_PATTERN}
最後に一致した正規表現パターンを取得できる変数が追加されました。
変更点
非推奨警告のカテゴリ分け
非推奨の機能に関する警告がカテゴリ分けされ、個別に無効化できるようになりました。
readlineが例外フラグをリセットしなくなった
readlineが例外フラグをリセットしなくなったため、コードの挙動が変わる可能性があります。
BEGIN内でのexit()の扱い変更
BEGIN内でexit()が呼ばれた場合、それ以降のINITブロックが実行されなくなりました。
構文エラー時のふるまいの変更
構文エラーが発生した時点で解析を止め、それ以降のエラーメッセージを出力しなくなりました。
'を使ったパッケージ名の非推奨化
'をパッケージ名の区切り文字として使うことが非推奨になりました。
smartmatchの非推奨化
smartmatchオペレータ(~~)が非推奨になりました。

その他にも、多くのモジュールとドキュメントの更新、バグ修正、内部改良なども含まれています。

use v5.36 で有効になる機能
signatures
signatures が有効になりますが、依然「実験的」なままなので use feature 'signatures'; は不要になりましたが、no warnings "experimental::signatures";は必要なままです。
isa
v5.32.0 で導入されたクラスインスタンス演算子が有効になりました。
use warnings
use warnings がディフォルトで有効になりなりました。無効にするには明示的に no warnings とします。プラグマはレキシカルスコープなので、本当に警告を消したいコードブロックに限定して無効化できます。
use false true is_bool
真理値関係の組込み機能が導入されました。真理値定数と、値がブール値の性質を持つかかどうかをチェックする is_bool() が導入されました。
defer
新興言語にありがちな defer が「実験的」ですがPerlに入りました。スコープで抜けたときに実行するコードブロックをキューに登録できます。
finally block
try/catchがfinal block を取れるようになりました「実験的」(意味的には errdefer に近いです)。
use v5.36 で無効になる機能
indirect object notation
$x = new Class()記法は廃止されました。$x = Class->new()記法を使ってください。
switch
v5.10 で導入された given/when は無効化されました。
@ary = sort ()
空配列を sort 関数に渡すことは不正になりました。
use < v5.11
use v5.11より前の use v5.xx は警告を出します。v5.11.xの一部から use strict がディフォルトでになったので、use strict を強く推奨する意図があるようです。

Perl 5.34.0の新機能と変更点

コア機能強化
  • 実験的な Try/Catch 構文が追加されました。
    use feature 'try';
    
    try {
        a_function();
    }
    catch ($e) {
        warn "An error occurred: $e";
    }
    
  • 空の下限が正規表現の数量詞で受け入れられるようになりました。
    m/x{,3}/  # m/x{0,3}/ と等しい
    
  • ブレース内には空白 (タブやスペース) が自由に配置できるようになりました。(二重引用符コンテキストと正規表現パターン内で)
  • 新しいオクタルリテラル構文として 0o が導入されました。既存の 0xddddd (16進数リテラル) や 0bddddd (2進数リテラル) と同様の方法で、0o123_456 のような表記が可能です。また、組み込み関数 oct() でもこの新しい構文が使えるようになりました。
パフォーマンス向上
  • 正規表現でのメモリリークを修正しました (GH #18604)
モジュールとプラグマ
  • 新しいモジュールとプラグマが Perl コアに追加されました。
    • ExtUtils::PL2Bat 0.004
  • 既存のモジュールとプラグマが更新されました。
新機能
  • 実験的な中置演算子 'isa': この演算子は、与えられたオブジェクトが指定されたクラスまたはその派生クラスのインスタンスかどうかをテストします。
  • Unicode 13.0 サポート: https://unicode.org/versions/Unicode13.0.0/ の詳細を参照してください。
  • 連鎖比較: 比較演算子を連鎖することができます (例: if ($x < $y <= $z) {...}).
  • 新しい Unicode プロパティ 'Identifier_Status' と 'Identifier_Type': 正規表現における有効な識別子のより精密なチェックが可能になります。
  • POSIX 関数の改良: mblen(), mbtowc, wctomb がシフトステートロケールで動作し、C99 以上のコンパイラでスレッドセーフになりました。
  • アルファアサーションとスクリプトリランはもはや実験的ではない: 警告なしで使用できます。
  • 高速な機能チェック: パーサー内での機能チェックのパフォーマンスが向上しました。
  • コンパイルされたパターンのダンプ: 正規表現コンパイルの問題をデバッグするのに役立ちます。
セキュリティ修正
  • バッファオーバーフローと作成された正規表現に関連する 3 つの脆弱性が修正されました。
非互換性の変更
  • 特定の機能は、Unicode プロパティ値のワイルドカード サブパターンをコンパイルする際に許可されなくなりました。
  • 使用されていない関数 POSIX::mbstowcsPOSIX::wcstombs が削除されました。
  • (?[...]) のバグ修正により、一部のパターンがコンパイルできなくなる可能性があります。
  • \p{user-defined} プロパティは、常に公式の Unicode プロパティをオーバーライドします。
  • 定数には変更可能な変数が許可されなくなりました。
  • コードポイントが 0xFF を超える文字列に対して vec を使用することは禁止されています。
  • 文字列ビットワイズ演算子で 0xFF を超えるコードポイントを使用することは許可されなくなりました。
  • Sys::Hostname::hostname() は引数を受け付けなくなりました。
  • プレーンな "0" 文字列は、範囲演算子に対して数値として扱われます。
  • \K は、先行アサーションと後行アサーションで使用できなくなりました。
パフォーマンスの向上
  • my_strnlen, grok_bin_oct_hex, grok_number_flags、および grok_regex を含むいくつかの関数が高速化されました。

これらの変更に加えて、Perl 5.32 には多くのマイナーな修正と改善が含まれています。 詳細については、Perl 5.32 のリリースノート https://perldoc.perl.org/ を参照してください。

Perl 5.30 は、2019 年 5 月 22 日にリリースされた安定版です。Perl 5.28 からの主な変更点は以下の通りです。

機能強化
  • 正規表現における制限付き後方参照のサポート: 正規表現で、最大255文字までの制限付き後方参照アサーションが使用できるようになりました。これにより、文字列内の現在の位置より前にあるパターンに基づいてマッチングすることができます。
  • 正規表現の修飾子の上限値の引き上げ: {m,n} などの修飾子で指定できる最大値が 32767 から 65534 に引き上げられました。
  • Unicode 12.1 サポート: Perl 5.30 は、最新の Unicode 標準である Unicode 12.1 をサポートしています。
  • Unicode プロパティ値に対する部分的なワイルドカードサポート: 正規表現でワイルドカードを使用して、Unicode コードポイントをそのプロパティに基づいてマッチングできるようになりました。例えば、qr!\p{nv=/(?x) \A [0-5] \z / }! は、数値が 0 から 5 の間の Unicode 文字すべてにマッチします。
  • qr'\N{name}' のサポート: Perl は、単一引用符で囲まれた正規表現内で、名前付き文字を直接使用できるようになりました。
  • シームレスなトルコ語 UTF-8 ロケールのサポート: Perl は、トルコ語で使用される "i" や "I" などの文字の異なる大文字小文字の規則を自動的に処理します。
  • オプションの スレッドセーフなロケール操作: Perl をコンパイルして、常にスレッドセーフなロケール操作を使用するようにすることができます。
  • パフォーマンスの向上: UTF-8 処理と正規表現マッチングの高速化など、パフォーマンスを向上させるためのいくつかの最適化が行われました。
非互換性のある変更
  • $[ に非ゼロを代入することは致命的エラー: 以前は配列と文字列の開始インデックスを設定するために使用されていた $[ 変数に非ゼロ値を代入することは、現在致命的エラーとなります。
  • 正規表現における区切り文字は字形素である必要がある: 正規表現で使用される区切り文字 (例: /pattern//) は、有効な字形素 (書記体系で表現できる文字) である必要があります。
  • エスケープされていない左ブレース ({) はエラー: エスケープされていない左ブレース ({) は、文字列リテラル内でのみ許可されます。

これらの変更に加えて、Perl 5.30 には多くのバグ修正とマイナーな改善が含まれています。

use v5.28 で有効になる機能
bitwise
use feature "bitwise";することなく、 文字列固有 (&. |. ^. ~.) および数値固有 (& | ^ ~) の ビット単位演算子が使えるようになりました。

Perl 5.28.0の新機能と変更点の概要

コア機能強化
  • Unicode 10.0への対応
  • ハッシュのスライスに対するdelete命令のサポート
  • 正規表現アサーションのアルファベット別名 (実験的)
  • 混合Unicodeスクリプトの検出
  • inplace (-i) エディタの安全性向上
  • 集計状態変数の初期化
  • フルサイズのinode番号
  • sprintfの %j フォーマット修飾子 (C99以前のコンパイラで使用可)
  • close-on-exec フラグのアトミックな設定
  • 文字列/数値専用のビット演算 (実験的ではなくなった)
  • スレッドセーフなロケール (対応システム上)
  • 新しい read-only プリ定義変数 ${^SAFE_LOCALES}
セキュリティ
  • 正規表現コンパイラのヒープバッファオーバーフロー (CVE-2017-12837) の修正
  • 正規表現パーサのバッファオーバーリード (CVE-2017-12883) の修正
  • Windowsにおける $ENV{$key} のスタックバッファオーバーフロー (CVE-2017-12814) の修正
既定のハッシュ関数の変更

Perl 5.28.0では、安全性が不十分とみなされる古いハッシュ関数が廃止されました。代わりに、Siphash (2-4および1-3のバリエーション)、Zaphod32、StadtXハッシュの4つの汎用ハッシュ関数がサポートされます。さらに、短い文字列のハッシュには、提供されている他のハッシュ関数と組み合わせてSBOX32 (一種の表形式ハッシュ) がサポートされます。

互換性のない変更
  • サブルーチン属性とシグネチャの順序
  • フォーマット内でのカンマ区切りのない変数リスト
  • ロックされたおよびユニークな属性の削除
  • ブレース({})内が空の場合の \N{}
  • ファイルとディレクトリハンドルの両方としての同じシンボルのオープン
  • ベア << による <<"" の表現
  • $/ を非正の整数の参照に設定すること
  • IV_MAX を超える Unicode コードポイント
  • B::OP::terse メソッドの削除
  • 非メソッドに対する継承 AUTOLOAD の使用
  • ビット演算文字列演算子での 0xFF を超えるコードポイントを持つ文字列の使用
  • ${^ENCODING} の設定 (Perl 5.22 以降は推奨されず、Perl 5.26 以降は機能停止)
  • -S スイッチでの PATH 環境変数内でのバックスラッシュによるコロンのエスケープ
  • デバッグ H フラグ (DEBUG_H) の削除
  • ... (yada-yada) 演算子はステートメントのみ
非推奨
  • 0xFF を超えるコードポイントを持つ文字列に対する vec の使用
  • 正規表現内でのエスケープされていない "{" の一部の用法
  • "(" の直後に続くエスケープされていない "{" の使用
  • $[ への代入 (Perl 5.30 でエラー)
  • hostname() への引数の渡し (Perl 5.32 で非推奨)
モジュールの削除

いくつかのモジュールは将来のリリースで core ディストリビューションから削除される予定となっており、その時点で CPAN からのインストールが必要になります。CPAN 上でこれらのモジュールを必要とする配布パッケージは、それらを前提条件としてリストアップする必要があります。

core バージョンのこれらのモジュールは、このような事実を警告するために "deprecated" カテゴリの警告を発行するようになりました。これらの非推奨警告を消すには、問題のモジュールを CPAN からインストールしてください。

パフォーマンス向上
  • 正規表現パターン (Unicode プロパティ (\p{...})) の作成時の起動オーバーヘッドがほとんどの場合で大幅に削減されました。
  • 内部的に複数回の連結とオプションで = または .= を 1 つの操作にまとめる multiconcat オペコードが導入されたため、多くの文字列連結式が大幅に高速化されました。
  • ref()組み込み関数は、ブール値のコンテキストでは、Foo=ARRAY(0x134af48) のような一時文字列を作成しなくなったため、はるかに高速になりました。
  • その他にも多数のパフォーマンス改善が施されています。
モジュールとプラグマ

このリリースでは、いくつかのモジュールで以下のような重要なハイライトがあります。

  • use vars の削除
  • ほとんどのモジュールで XSLoader への DynaLoader の使用変更
  • モジュールの更新とプラグマ


脚註

編集