Subscribed unsubscribe Subscribe Subscribe

Flymake時にPERL5LIBを通すシンプルな方法

2012-02-28: 少し追記しました

今どきの(?)flymakeは賢くてflymake-perl-initとか自分で書かなくてもflymake-modeを有効にするだけでほとんどの設定を勝手にやってくれて便利。
flymake話まだひっぱりますよ - taiyoh独言
なので、Perlのflymakeの設定は

(defun my-cperl-mode-hook ()
  (perl-completion-mode t)
  (flymake-mode t)
(add-hook 'cperl-mode-hook 'my-cperl-mode-hook)

だけでもそれなりに動いてくれるわけですね。


問題となるのはWebアプリとか自作モジュールを含めたプロジェクトで.pmファイルとかを編集しているときにlibにパスが通ってないと依存モジュールをロードできなくてflymakeがエラーを返してしまうとき。
そのpmファイルの上位にあるlibディレクトリをPERL5LIB環境変数に加えることでこれを防げる、ということでset-perl5lib.elを使っている人が多い、ような気がする。
/lang/elisp/set-perl5lib/set-perl5lib.el – CodeRepos::Share – Trac

でもこのset-perl5libってpmファイル開くたびにどんどん対応するlibディレクトリをPERL5LIBに加えていくことになる(plcmp-cmd-show-environmentコマンドで確認できると思う)ので、複数のプロジェクトを編集していたりすると環境が汚染されていってしまって正しい動作にならないこともあるんじゃないかな、と思ったりしていてあまり良い方法な気がしない。もっと良い方法は無いんだろうか?

提案(?)

Emacs&Perl使いが絶対使っていると思われるperl-completion.elにはplcmp-with-set-perl5-libというマクロが定義されていて、内部ではplcmp--get-lib-path-list-liberalなどで取得したlibディレクトリを"一時的に"PERL5LIBにセットして処理を行う、ということをしてくれる(このlibディレクトリ取得のロジックはちゃんと検証してないけどおそらくset-perl5libと同じで上位に辿って"lib"というディレクトリを探索しているはず)。
なので、ファイルを開くたびにPERL5LIBに追加するんじゃなくて、flymakeが裏でsyntax checkのためのコマンドを実行するときにだけPERL5LIBが追加されるように

(defadvice flymake-start-syntax-check-process (around flymake-start-syntax-check-lib-path activate)
  (plcmp-with-set-perl5-lib ad-do-it))

と、defadviceのaroundでやってしまう方法を使ってみた。
https://github.com/sugyan/dotfiles/blob/b1401ad505495239f15b4ff95d8600f9ae36ebc0/.emacs.d/inits/21-perl.el
とりあえずコレで余計なパスがPERL5LIBに追加されることもなく、ロードできないエラーが起こることもなく快適にflymakeが使えている気がする。


こうしたいflymake - unknownplace.orgの記事のコメントに書いてあるのはどういう方法で実現しているんだろう…?

追記(2012-02-28)

@さんからブコメでご指摘いただきました。最近は以下のような形でやっている、とのこと
perlbrew.elとProject::Libsを使ったflymakeの設定 - Kentaro Kuribayashi's blog
perlbrew云々は今のところあまり困っていないけど、Project::Libsを使ってsyntax checkを実行させる方法は確実で良いなと思いました。ヘタにelisp側でPERL5LIBをゴニョゴニョしようとすると混乱するので。
@さんに訊いてみたところでは perl-completionでset-perl5libと同様にPERL5LIBに勝手に追加される、とのことだったけど自分の環境でほぼまっさらな状態にして試してみた限りでは少なくとも勝手に環境に追加されるようなことはなかった。とりあえず今はもうset-perl5libを使わなくてもplcmp--get-lib-pathなどで加えるべきパスを取れるのでperl-completionだけで問題無い、というのは間違い無さそう。

自分としてはProject::Libsが必要になるようなディレクトリ構成じゃない限りは前述のdefadviceを使った方法で良いかな、と思っています。