僕の perlbrew の使い方の話。だいたいネットのあちこちに載ってる話なのだけど、まとめてみた

そもそもなぜ perlbrew を使っているか

OS に付いてくる Perl (System Perl) をそのまま使うのはあまり良くない、と言われているってのと、最新版とか、特定のバージョンを使いたい場合があるためです。

plenv ではなく、perlbrew なのはどうして?

基本的には lib を使いたいから。plenv もプラグイン入れると lib 使えるっぽいので、乗り換えても良いのかもだけど、めんどくさい。

perlbrew のインストールとか

ぐぐれば出てくるし、公式にも普通にのってるので、頑張って!(頑張らなくても大丈夫なはずですが)

perlbrew lib

perlbrew は lib という便利な機能があって、モジュールを入れるディレクトリを lib ごとに切り替えることができます。

こんな感じの機能です。まじ便利。

tsucchi@surreal[505]$ perlbrew lib --help

Usage: perlbrew lib <action> <name> [<name> <name> ...]

    perlbrew lib list
    perlbrew lib create nobita
    perlbrew lib create perl-5.14.2@nobita

    perlbrew use perl-5.14.2@nobita
    perlbrew lib delete perl-5.12.3@nobita shizuka

便利なのですが、がっつり使っているわけではなくて、割と単純な指針でやっています。

  • default という lib を作って、モジュールは基本そこに入れる
  • 最初に入れた perl 自体にはモジュールを入れない(し、入れられないようにする)

まず、欲しいバージョンの Perl をインストールして、default という lib を作ります。 install では --as を使って、メジャーバージョンを固定しておくのがポイントかな。 lib に必要なモジュールをインストールしていきます。

tsucchi@surreal[506]$ perlbrew install perl-5.20.1 --as perl-5.20
...
tsucchi@surreal[507]$ perlbrew lib create perl-5.20@default
tsucchi@surreal[508]$ perlbrew switch perl-5.20@default
tsucchi@surreal[509]$ cpanm iroiro-na-module

あとは、うっかり素の Perl (lib じゃない方)にモジュールを入れないように、ファイルシステムレベルでロックをかけるようにしています。 (perlbrew lib では ~/.perlbrew 以下にモジュールが入るので問題無い)

Linux の場合

tsucchi@surreal[510]$ cd perl5/perlbrew/perls/
tsucchi@surreal[511]$ sudo chattr +i -R perl-5.20

Mac の場合

tsucchi@surreal[510]$ cd perl5/perlbrew/perls/
tsucchi@surreal[511]$ sudo chflags -R uchg perl-5.20

マイナーバージョンアップ

Perl はマイナーバージョンアップ(5.20.0 -> 5.20.1 みたいな)の場合、バイナリレベルの互換性が保証されているので、モジュールを入れ直したりする必要はありません。 perlbrew に upgrade-perl というコマンドがあるので、これを使っています。

前述のように、素の Perl にはファイルシステムレベルのロックをかけているので、バージョンアップ時にはこれを外しています。(で、終わったら戻す)

Linux の場合

tsucchi@surreal[510]$ cd perl5/perlbrew/perls/
tsucchi@surreal[511]$ sudo chattr -i -R perl-5.20
tsucchi@surreal[512]$ perlbrew use perl-5.20
tsucchi@surreal[513]$ perlbrew upgrade-perl
...
tsucchi@surreal[514]$ sudo chattr +i -R perl-5.20

Mac の場合

tsucchi@surreal[510]$ cd perl5/perlbrew/perls/
tsucchi@surreal[511]$ sudo chflags -R nouchg perl-5.20
tsucchi@surreal[512]$ perlbrew use perl-5.20
tsucchi@surreal[513]$ perlbrew upgrade-perl
...
tsucchi@surreal[514]$ sudo chflags -R uchg perl-5.20

メジャーバージョンアップ

メジャーバージョンアップというか、新しいメジャーバージョンが出た場合は、基本的には新規インストールと同じです。 旧バージョンから、入れてるモジュールをリストアップして、新バージョンに移行したりしています。

5.18 -> 5.20 にあげる例だとこんな感じ。

tsucchi@surreal[512]$ perlbrew use perl-5.18
tsucchi@surreal[513]$ perlbrew list-modules > /tmp/modules.txt
tsucchi@surreal[514]$ vi /tmp/modules.txt
...
...(もう使ってないモジュールを消したりとか)
...
tsucchi@surreal[515]$ perlbrew install perl-5.20.1 --as perl-5.20
...
tsucchi@surreal[516]$ cd perl5/perlbrew/perls/
tsucchi@surreal[517]$ sudo chflags -R uchg perl-5.20
tsucchi@surreal[518]$ perlbrew lib create perl-5.20@default
tsucchi@surreal[519]$ perlbrew switch perl-5.20@default
tsucchi@surreal[520]$ cpanm < /tmp/modules.txt

list-module を使って新しい Perl にモジュールを移行するのはワンライナーでかっちょよくやるのも可能なのですが、 僕は変なモジュール使ってないか確認したりしてるので、上記のような愚直な感じにしています。

素の Perl を残しておくのはなんで?

あんまりないのだけど、あるモジュールが壊れてインストールできなくなったりした場合に、検証する場合とかに、モジュールが全く入ってないPerlがあると早いんですね。 (依存関係がぶっ壊れてる場合の調査とか)。こういう時は、test って lib を作って調査します。

tsucchi@surreal[512]$ perlbrew lib create perl-5.20@test
tsucchi@surreal[513]$ perlbrew use perl-5.20@test
tsucchi@surreal[514]$ cpanm nanka-hennna-module
...
...(ログとかエラーメッセージを見て調査)
...

終わったら lib を戻して、消しています。

tsucchi@surreal[515]$ perlbrew use perl-5.20@default
tsucchi@surreal[516]$ perlbrew lib delete perl-5.20@test

ツールなどについて

@papix さんの 最近のplenv/Cartonの運用 にて言及いただいたこともあり、追記しました。(本節は2016/11/19に追記しています)

僕の場合、深遠な理由により会社ではデフォルトは System Perl になっており、そのため prt とか countperl とか riji とか reply とかその辺の便利ツールを使おうとするといちいち切り替えないといけなくて、とても面倒で、これは @papixさんの記事にもある通りです。

で、僕は使いたいツールはさほど多くないので、力技で解決、具体的には alias を使ってごまかしています。こんな感じ。

新しいバージョンの perl も newperl っていう alias で実行できるようにしているので、ガッツリ使いたい時以外はあまり perlbrew も切り替えていなかったりします。

参考にしたサイト

いろいろあるけど、下記は読んだことないなら一読しておくと良いと思います。

以上、他にも色々ある気もするのだけど、とりあえず思いつくものはだいたい書いた感じです。