hkoba blog

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

-nle と .pm から始める Perl 入門とかどうかしら?(後編)

-nle と .pm から始める Perl 入門とかどうかしら?(後編)

この記事は Perl Advent Calendar 2019 の 12/5 の記事です。内容は主に職場で Perl教える側 の人に向けた、提案です。


コマンド行からエディタ+ファイルに移る時

昨日の記事は、Perl 屋の新人教育を コマンド行ツールとしての Perl から初めてはどうかしら?という提案でした。

今日の記事は、その新人さんの教育が進んで、コマンド行では収まらず、 エディタ+ファイルを使いたい規模に進んだ時に、今までどおりに *.pl の書き方を教え続けるのが良いのだろうか? いやむしろ、 コマンド行の次は即座に *.pm の書き方を 教えては?という話です。

.pl 飛ばして、 .pm から教えては?案

私が *.pm の書き方から教えることをお勧めする理由は、以下の2点です。

  1. 仕事で Perl を書く人の場合、モジュールの読み書きは避けては通れないから。
  2. *.pm*.pl を兼ねることが出来る(後述の Modulino)が、逆は違うから。

職場にもよるでしょうが、 今の時代に Perl を書くお仕事は、新規開発よりも保守改良のお仕事の方が多いのではないでしょうか。 その保守改良では、既存の業務のコードベースのモジュール群(つまり *.pm)を読み書きする能力が 不可欠です。だとしたら、 *.pl を学ぶことは新人さんにとって回り道なのではないか? という疑問があるのです。

もちろん *.pl*.pm よりもプログラミングの際の決まり事が少ないのは事実です。 教育の初期において負荷は少ないほうが良いという意見も分かります。 ただ、その部分はコマンド行の Perl でカバーしても良いのではないでしょうか?

何より、新人教育期間はただ知識を吸収するためだけではなく、 トレーニングのために確保された期間でもあります。 トレーニングは今後の仕事で必要となる作業に対して、その負荷に慣れて自然に動けるように力を 成長させるためのプロセスです。最終的に職場で要求されるのが *.pm であるなら、 その負荷に慣れるトレーニングを早めに始めることが大事なのではないでしょうか?

念のため、 *.pl, *.pm の長所・短所を整理してみます。

.pl の長所・短所

  • *.pl の長所
    • コマンド行の Perl で学んだこととのギャップが無い
    • ファイル名に制約が無い (拡張子が .pl である必要すら、無い)
    • #!/usr/bin/perlPerl のコマンド行オプションを書ける(制限有り)
  • *.pl の短所
    • *.pl ファイルをただ書いても、require, use で使えるモジュールにはならない。
      • == *.pl の中の関数を他のファイルから呼び出せない。
      • == ファイルの一部分だけを簡単に試す、ことが出来ない
        • 簡単に試せるように、仕様を絞って関数を書く、という動機が発生しない
    • テストを書くのが難しい
    • 結局 *.pl で書いたコードは単一の用途・文脈でしか役に立たないコードになる。

.pm の長所・短所

  • *.pm の長所
    • require, use, perl -Mモジュール名 で他のプログラムに読み込める
    • ファイルの一部の関数を他のファイルから呼び出す、という事が可能になる
      • == 呼び出した時に便利になるように、仕様を整理する動機も生まれる
    • テストを書くために Perl の標準的な道具が利用できる
  • *.pm の短所
    • モジュールの書き方の約束に従う必要が有る
    • ファイル名を(*.pl の時よりは)真面目に考える必要が生じる。(拡張子も .pm固定)
    • *.pm を実行可能にするには、 Modulino の書き方を覚える必要が有る

実行可能な Perl モジュール (Modulino = モジュリーノ)の書き方

では具体的に、新人教育でモジュールの書き方をどう教えればよいのでしょうか? 私は (Modulino = モジュリーノ) と呼ばれる書き方を使って、 スクリプトとしても実行可能なモジュールを書いてもらうことを提案します。

最初のモジュールは、おもちゃでも構いません。 むしろ怖がらないで済むように、おもちゃで始めるのが良いのではと思います。

例えば *.pl で最初に教えてきたのが print "Hello world!\n" なら、 同じことを実行可能なモジュールで教えれば良いでしょう。 練習ですから、ファイル名も細かいことは言わないで、ストレートなものが良いでしょう。

Hello.pm

#!/usr/bin/env perl
package Hello;

unless (caller) {
  print "Hello world!\n"
}

1;

あとはこのファイルに実行 permission を与えて、動かすのみ。

% chmod a+x Hello.pm
% ./Hello.pm
Hello world!
% 

モジュールとして読み込む場合はこうなります。

% perl -I. -MHello -e0
%

ただこれだと何も起こらなくて、嬉しさが伝わりませんね。 なので、教育の中で『関数が必要な題材』が出てきた段階で、初めて作る Perlスクリプトファイルとして *.pm の書き方を教える、というのが良いのではないかと思います。

行儀の良いモジュールの書き方に、どうシフトしていくか?

上で挙げた例の Hello.pmuse strict; use warnings が無いことを見て、 凍りついた人もいるかもしれません。業務に耐えるレベルのモジュールを書ける人になってもらうためには、 勿論、避けて通れない話です。この点は教育課程の練りどころで、私も現在、研究の最中です。 皆さんと情報交換していけたら有り難いです。

一つ言えるのは、コマンド行 Perl の教育と *.pm ファイルの教育は 必ずしもスパッと二期に分ける必要はないのではないか?ということです。例えば コマンド行で課題をしてもらっている中で、新人さんが変数の typo で苦労をし始めていることを 観測したら、その時点で *.pm ファイルの書き方に教育をスイッチして use strictmy を教える、というようにです。また逆に、新しい機能を紹介する時は、まず最初にコマンド行で実演してみせる、という手も有りえます。

多人数の同時教育では難しいかもしれませんが、ペア・プログラミングで徒弟的に教育を進められる場合は、 有力な方法ではないかと思います。(教育プロセスにもTMTOWTDI、なんちゃって…) Perl教育すごろくとかあると面白いかも…〇〇に詰まったら☓☓を教える、みたいな)

まとめ

職場の新人さんに向けた Perl教育で、コマンド行ツールとしての Perl を教えた後は 即座に Modulino で *.pm の書き方を教えるのはどうでしょう?という提案でした。

(実は Modulino の書き方に関してはFile::AddInc で @INC を調整する話とかオブジェクト化とサブコマンドの話とか use fields でオプションを表現する話とか引数/出力のJSON標準化の話とかネタは色々有るので、アドカレの空きが有ったら書くかもしれません…書けないかもしれません…><)

Perl Advent Calendar 2019, 明日の担当は, AnaTofuZ さんです.