hkoba blog

プログラマーです。プログラミング言語ミーハーです。ツッコミ歓迎です。よろしくどうぞ(能代口調)

zsh 上で .pm のメソッド名を補完する話

この記事は Perl Advent Calendar 2020 の 12/3 の記事です。

想定読者は、自分で Perl のモジュールを書く機会が有り、かつそのモジュールのメソッドをコマンド行からさっと試したい! と思ったことの有る人です。


Perlモジュール(.pm ファイル)を実行可能なスクリプトにする技法(モジュールに unless caller で直接実行時の処理を書いておく)は 90年代から存在し、Modulino (モジュリーノ)という名前でも知られています。 更にオブジェクト指向のクラスとして書かれた Modulino にメソッドディスパッチの機能を持たせて OO な Modulino とする手法は、多くのメソッドをコマンド行から即座に試せるため、一層便利です。 私も何度か記事勉強会で発表してきました。もちろん私が仕事で新たに書く Perl モジュールは原則として全て OO Modulino です。

ただ、そんな私でも、半年前に書いたモジュールを久しぶりに使う時などは、そのモジュールがどんなメソッドを実装しているかをもう忘れているのが普通です。そのため、例えコマンド行からメソッドを呼び出せる仕組みが有ったとしても、 結局 ソースを一通り眺めて適切なメソッドを探すという無駄な時間 を要していました。

ここでもし、シェルのコマンド行の補完機能で、メソッドやオプションの名前(と、その説明文)の一覧を見ることが出来たら、(その後でソースを確認する必要は残るとしても)適切なメソッドを探す時間を大分節約できるのではないか…? そう考えて実装したのが、 zsh の completer、 _perl_oo_modulino です。(CPAN に公開済み)

デモ動画を用意しましたので、良ければご覧ください(無音、約2.5分)

デモコードのリポジトリこちらです。 デモ用に、業務コードからメソッドやオプションとその解説文だけを切り出したものです。解説文を定義している部分を以下に抜粋します>

付録

簡単に試したい

デモコードに Dockerfile を用意したのでお試し下さい。run すると zsh が起動します。 上記の demo3 が workdir /data/ の下にあります。

hkoba の Base クラスって何?

こちらです。(長い名前なので、私は普段 CLI_JSON と呼んでいます)>

MOP4Import::Base::CLI_JSON - metacpan.org

この CLI_JSON を継承したクラスじゃないと動かないの?

必ずしも継承する必要はない(はず)です。

  • CLI のサブコマンドをメソッドへとマップする、 OO な Modulino になっていれば、意味の有る補完が出来るはずです。

    • メソッドの解説は code attribute から取得しています。ですので、 :Doc() を定義・取得出来るよう、 MODIFY_CODE_ATTRIBUTES と FETCH_CODE_ATTRIBUTES を実装する必要があります。
      • とはいえ現状では取得側は my ($atts) = grep {ref $_ eq 'HASH'} attributes::get(\&method); $atts->{Doc} みたいなコードです。attributes の使い方を間違っている可能性もあります。ツッコミ希望です。
  • CLI のオプションを %FIELDS で定義したフィールド(メンバー変数)へとマップする仕組みなら、オプション名の補完も効くはずです。

    • オプションの解説は $FIELDS{フィールド名}->{doc} から取得しています。

zsh 側はどういう仕組み?

zsh には コマンド名のパターンに対する補完関数を定義する機能 compdef -P があります。これを使えば拡張子 *.pm 全てに対する補完を定義できます。

bash に同等の機能が有るかどうかは分かりません。有れば実装できる可能性は有ります。


以上です

読んで下さりありがとうございました。明日の記事は utgwkk さんです。