LoginSignup
30
23

More than 5 years have passed since last update.

CentOS 標準搭載の Perl に負けないで強く生きる

Posted at

この記事では、OS 標準の Perl で動く CLI ツールを作ってる際に CentOS でハマる点について説明しています。

TL;DR

  • Linux / Mac OS X の多くの環境では標準で Perl 5 がインストールされいる
  • しかし CentOS 標準の Perl 5 の コアモジュールは欠けている
  • OS 標準の Perl に依存した CLI ツールを作る時は注意が必要

なぜ標準インストールの Perl を使う必要があるのか

現在使われている Linux の多くや Mac OS X には、標準で Perl 5 がインストールされています。

しかし、Perl でウェブサービスを開発する際には、それら標準でインストールされている Perl ではなく、独自でインストールやビルドした Perl を使うことになるでしょう。

しかし、日常的に Perl を使っている人向けではない CLI ツールであったとしたら話は別です。
そのツールを使うために、別途 Perl のインストールをさせるのは避けたい。

たとえば、私が開発しているコマンドラインツールである crenv のバックエンドである crystal-build は、上記の理由により OS 標準の Perl を使って動いています。

corelist コマンド

corelist コマンドを使うと、モジュールが Perl のコアモジュールであるかどうかを調べることができます。

以下のように実行すると、JSON::PP は Perl v5.13.9 以降はコアモジュールであり、JSON::XS はコアモジュールに含まれないことが分かります。

$ corelist JSON::PP

JSON::PP was first released with perl v5.13.9

$ corelist JSON::XS

JSON::XS was not in CORE (or so I think)

つまり、corelist で調べてからモジュールを使えば、環境によるコアモジュール差異の問題は生じないはずです。と思っていた時代が私にもありました。

CentOS の標準 Perl のコアモジュール

しかし CentOS の標準の Perl には、コアモジュール が欠けている問題があります。
具体的にどのようなモジュールが欠けているのか、簡単なスクリプトを記述して確かめてみます。

以下のスクリプトに対して $ ./corelist.pl 5.016003 のように実行すると、ある特定のバージョンに含まれているべきコアモジュールを検査するスクリプトが書きだされます。

(CentOS の標準 Perl のコアモジュールに Module::CoreList が含まれていないため、このように遠回りな手法を取っています)

corelist.pl
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;

use Data::Dumper;
use Module::CoreList;

local $Data::Dumper::Terse = 1;

my $perl_version    = $ARGV[0];
my $module_versions = Module::CoreList::find_version($perl_version);
my @module_names    = sort keys %$module_versions;
my $data            = do { local $/; <DATA> };
my $source          = sprintf($data, Dumper(\@module_names));

print "$source\n";

__DATA__
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;

open(STDERR, '>/dev/null');

my $module_names = %s;

for my $module_name (@$module_names) {
    eval "require $module_name";

    if ($@) {
        print "$module_name ERROR\n";
    }
}

実行して出力したスクリプトを調べたい環境で実行すると、どのモジュールが存在しないかが分かります。

以下は、Amazon Linux AMI 2015.09.1 の初期状態の Perl v5.16.3 で存在しないモジュールの一例です (括弧内は、コアモジュールとして存在するはずのバージョン)。

  • Archive::Tar (>= v5.9.3)
  • JSON::PP (>= v5.13.9)
  • Module::Load (>= v5.9.4)
  • Test::More (>= v5.6.2)
  • version (>= v5.9.0)

たとえば、Perl で書かれた nodebrew は、コアモジュールが欠けた状態の CentOS で動作させるため このように Archive::Tar モジュールから tar コマンドへフォールバックするコードが記述されています。

CentOS の標準 Perl で標準モジュールを有効にする方法

実は CentOS では一部の Perl コアモジュールは別のパッケージとして独立しています。
以下のようにしてインストールが可能です。

[ec2-user@ip-172-31-15-126 ~]$ sudo yum search perl-core
Loaded plugins: priorities, update-motd, upgrade-helper
==================== N/S matched: perl-core ====================
perl-core.x86_64 : Base perl metapackage

  Name and summary matches only, use "search all" for everything.

[ec2-user@ip-172-31-15-126 ~]$ sudo yum install perl-core -y

なぜ CentOS の Perl ではコアモジュールが省かれているのか (考察)

これは、Ubuntu と違い CentOS が Perl ではなく Python に強く依存する OS であるからであると考えられます。

私は、Perl コアモジュールとして定義されているものは、どの環境にインストールされた Perl でも存在するべきであると思います。なぜならば、コアモジュールがインストールされている前提でスクリプトを記述するからです。

しかし、このような状況であるため CentOS のコアモジュールが欠けた状態を考慮してコードを書く必要がありますので、ご注意を…。

まとめ

  • Linux / Mac OS X の多くの環境では標準で Perl 5 がインストールされいる
  • しかし CentOS 標準の Perl 5 の コアモジュールは欠けている
  • OS 標準の Perl に依存した CLI ツールを作る時は注意が必要
30
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
23