-nle と .pm から始める Perl 入門とかどうかしら?(前編)
-nle と .pm から始める Perl 入門とかどうかしら?(前編)
この記事は Perl Advent Calendar 2019 の 12/4 の記事です。内容は主に職場で Perl を 教える側 の人に向けた提案です。
(今から仕事で Perl を学び始める人は、多分 Linux/Unix 環境に関わる人であろう、と想定しています。違ったらごめんなさい。)
初めて書く Perl は何が良い?
皆さんは職場の新人さんに Perl を教えるとき、初めにどんな形式でプログラムを書いてもらっていますか?
普通は何らかのエディタで foo.pl, hello.pl のように *.pl
ファイルを作ってもらって実行、ではないかと思います。この方法は、使い慣れたエディタが有る人には最も安心感を与える方法でしょう。
ですが、この方法には二つの弱点があるのではないでしょうか?
$_
などの特殊変数や、その省略法則(ex.デフォルトのm//
の対象、split
の第2引数、-X
テストの対象…)を教える切っ掛けが乏しい*.pm
形式のモジュールの書き方が先送りされる
そして何より、 今さら、 Perl を学ぶメリット を語る力が弱いのではないか?と私は思うのです。 1990年代ならともかく、現代では Perl は Python, Ruby, PHP そして JavaScript と 強く比較しながら使われる時代です。今さら何故 Perl? という問いに答えを用意してあったほうが、 学ぶ人も意欲を持ちやすいのではないかしら?という考えです。
最初はコマンド行のワンライナーから、でどうでしょう?
その意味で、私は、最初に教える Perl はコマンド行での perl -nle …
が良いのではないか?
と考えます。何故なら、 コマンド行ツールとしての Perl の強さは、2020年代を迎える今でも十分な輝きを保っているからです。幾つか挙げるなら、
- とにかく記述量が少ない。なのに、大きな働きをしてくれる
- 起動が速い、実行速度も十分速い、もちろんビルド不要
- 多くの Linux/Unix 系システムで、環境構築作業をほぼせずに、使い始められる
- コア機能だけで十分役に立ってくれる(パッケージ管理の勉強を後回しに出来る)
- 仕様が長期に渡って安定している
つまり、コマンド行ツールとしての Perl から始める理由は、簡単に学習を始められる上に、努力と得られるメリットの比率も抜群だからです。
また、Perl を学ぶ時の難所である $_
などの特殊変数やその省略法則を教えるという点でも、
コマンド行スタートにはメリットが有ります。何故なら、それらが
ワンライナーを少しでも短く楽に書けるように設計された、lwall からのギフトだからです。
なのにコマンド行を全く避けてしまうと、その短い記法が分かりにくさ・読み難さの元凶、
害悪にしか思えなくなるでしょう。説明する側も言い訳がましくなり、辛いところです。
他にも副次的効果を何個も挙げられます。
- shell と端末に馴染む機会にもなる
- 特にワンライナーを書いてすぐ試す、リズムを会得できる。これは後のプログラミングにも有効。
- sed, awk などの作ってきた Unix 文化の説明の良い機会にもなる
- ミスが増えるので、
perl -w
の説明も導入しやすい perl -d
のデバッガに馴染む切っ掛けにも繋げやすい (ただし Term::ReadLine::Gnu の導入を推奨)- 段々プログラムが複雑化する過程で、変数名の綴り間違いの怖さに気づく切っ掛けにもなり、
use strict
の意義を伝えやすくなる。 BEGIN {}
,END {}
を教える切っ掛けも作りやすい
この教育方法の弱点
この方法の弱点は、学習の記録を残すことが難しいことです。 学習の効果を定着させるには、学習者が学んだことを容易に振り返って復習出来ることが大事です。 しかしコマンド行は一過性の側面が大きいため、そこを不安に(不安定に)感じる人もいるでしょう。
これについては、以下の対策が有りえます。
- シェルのヒストリー機能とそのダンプ方法(
history -w, fc -W
)を初期に教える。- ヒストリーのダンプを git に保存しても良いかもしれない
- コマンド行の短縮記法を教えた後に、
B::Deparse
を使いながら冗長な(省略を廃した) 記法も教える。それをスクリプトファイルとして残し、これを git に保存する。 - いっそ script コマンド で全て記録するとか? ttyrec? asciinema?
組織を超えた教材化は難しいかも?
あとひとつ難しいかもしれないのは、コマンド行での Perl の使い方は環境(組織、文脈)に特化する面が大きく、 汎用の教材を作りにくい、かもしれないことです。例えば業務の副次的なプログラムのエラーログから 情報を抜き出して DB に投入するとか…それが一般的で頻出する問題なら、既に専用のプログラムが 作られていたり、予め構造化してログを吐くことが出来ているはずです。 (もっと良いツールがあるのに何で自分で書くの?と言われると…教える時の言い訳が増えますね…内容次第ですが…)
なので、教育のためのシナリオと、そこで使うデータセットの準備が、最も 手間取る所になりそうです。
(適切なツールが既に存在しても、それを探し出すのに何十分もかかるなら、自分でさっとスクリプトを書いたほうが早い、というケースの話も、しても良いかもしれません)
とはいえ、既存の教材も無くはないので、例えば↓この辺りから 題材を抜き出しつつ教えるのも良いかもしれません。
あと、同じくフィルタに向いた言語のご先祖様であるプログラミング言語AWKの本からも例題を拾えるかもしれません。
- 作者:A.V.エイホ,P.J.ワインバーガー,B.W.カーニハン
- 出版社/メーカー: USP研究所
- 発売日: 2010/01/01
- メディア: 単行本(ソフトカバー)
まとめ
Perl 屋の新人教育、最初はコマンド行の Perl から初めてはどうかしら?という提案でした。
では、学んだコードをファイルにしたくなった時、 *.pl
に入れるのが良いのだろうか?
いやむしろ、最初から *.pm
で学ぶと良いのでは?
そういう話を明日の後編記事に書きます。
odc2019 聞きに行ってきました
odc2019 (オープンデベロッパーズカンファレンス) に初めて行ってきました。非常に勉強になりました!
聞けたトーク
(本当は朝から行きたかったのですが、うっかり宅配便の受け取り予定を入れてしまって…お昼からに…)
日本語入力の危機を乗り越える インプットメソッド・フレームワークとかな漢字変換に訪れている課題とその対策
私も Fedora Linux を使っていて日本語入力には日々お世話になっているので、動向把握のために行きました。
- これまでは GUI ツールキットと日本語入力フレームワークの組合せは GTK_IM_MODULE や QT_IM_MODULE を通して選択可能だった。 xim / uim / ibus / fcitx …
- 今後は Gtk4 や Qt5? 等々が直接 ibus を話す方向に進んでいる、とのこと。ibus (protocol? api?) がデファクト標準化しつつある模様。
- 最新の Debian で Gnome が Wayland ベースになった際に、従来の
/etc/X11/...
の仕組みが使われなくなり、 日本語入力が出来ない問題が起き、 im-config周りに変更を入れた。 - Waylandにはカーソル位置を取得する API が無い??(ゆえに変換ウィンドウの位置を制御できない??)
個人的には、 ibus がデファクト標準の地位を得つつ有るらしい、という情報が一番有益でした。 (Fedora ユーザーなので ibus をずっと使っているものの、他の仕組みに切り替えるほうが良いのかも?という迷いがずっと有ったので…)
運用ドキュメント2019 ~ 手軽にスピーディに継続的に保守するためのドキュメント入門~
資料公開しました。
— HATANO Hirokazu (@tcsh) 2019年8月24日
運用ドキュメント2019 〜 手軽にスピーディに継続的に保守するためのドキュメント入門https://t.co/joEp2YCkQx
#opendevcon
私も職場での運用手順や開発関連のドキュメントをどう構築管理するのが良いか悩んでいるので聞きに行きました。非常に耳に痛い、有益な主張がてんこ盛りでした。流石にそこを本業にしている人は切れ味が鋭いなぁと。
そもそも運用ドキュメントとは何のためのものか?からストーリーが組まれていたので、議論について行きやすかったのも有難かったです。
#opendevcon pic.twitter.com/qQ1KmttBsO
— Shinji Enoki (@eno_eno) 2019年8月24日
運用ドキュメントのレベル
— Miyahan (@miyahancom) 2019年8月24日
Lv0.記録: 事実であること(言語化)
↓
Lv1.整理: 論理的に正しいこと(論理化) → 知る
↓
Lv2.客観化: 客観的であること(抽象化) → 説明する
↓
Lv3.脱属人化: 再現性があること(具体化) → 永続化#opendevcon
運用ドキュメントのレベル
- Lv0.記録: 事実であること(言語化)
- Lv1.整理: 論理的に正しいこと(論理化) → 知る
- Lv2.客観化: 客観的であること(抽象化) → 説明する
- Lv3.脱属人化: 再現性があること(具体化) → 永続化
刺さったスライドを挙げていくと切りがないですが…
「運用業務をドキュメント化しないと、会社として、無い仕事にされる」(忙しそうだけど、何してるのか分からない、になる。 Job Description 化のススメ)
- 一方日本は「聞き手責任」 分からないやつが悪い…
スライドに無い話も非常に興味深かったです。
- 35歳の壁の話(固有名詞が出てこなくなる)とか。←言われてみれば自分もそうだったかも!
- 運用ドキュメントを即興 shell script で組み立てる(組み立てられるように、パーツとなる文書を貯めていく)という話も驚きでした。
- そして↑そういう事をするには sphinx が適している(というか include が大事)とのこと。やっぱりそうですか… (mdBook とかでも行けるかしら?)
懇親会も楽しかったです
libreoffice の方や opensuse の方が同テーブルでした。unix/linux の話が普通に出来るのは、やはり有り難いですね。(Windows や Mac が支配的な世界だと、ちょっと肩身が狭くて…) (迷惑だったかもですが)私が仕事先のチームで何故 XWindow の業務環境を維持しているのかという話も聞いてもらえて。 前田薫さんにも Runnable Module + JSON CLI や自作テンプレートエンジンの話を聞いてもらったり。逆に TypeScript/Go/Python の書き味の比較の話を聞かせてもらったり。
他人に説明する過程で自分がその立ち位置を選んだ理由を明確化できるので、こういう対話の機会はやはり有り難いです。そして、自分の主張を予めブログにまとめておけば良かったなと反省したり…ライブラリーの添付マニュアルや(発表のスライドは書いて公開しても、ブログに書いてないものが多いなと)
というわけで、今後はもっとブログに主張を残そうと思います、はい。
五反田pm#19 楽しかったです〜
五反田pm#19 に参加してしてきました。
感想あれこれ
@kfly8 さんと運営の皆様お疲れ様でした! 最近では珍しく Perl の濃い話を全力で話してもドン引きされるどころか喜ばれる会で、とても有難かったです。 懇親会のお酒とお寿司も美味しかったです!モバファクさんありがとうございました!
- 最初のコマンド行 Perl の話から質問が出て皆で答えて盛り上がりましたね〜
- JSON 関連モジュールの知見が色々聞けて勉強になったです。
- Perl TeX の話はびっくりしました。 TeX であそこまで出来るんですね…
- 初心者枠からの Perl で辛い所の話も、リファレンス、コンテキストと、あー詰まるよね分かる有るある!って感じで。
- PadWalker 登場で盛り上がるの、とても好きです〜
- トミールさんの、Perl での経験が Erlang や Golang でも色々思い出される話も良かったです〜。
私の発表
私は3月頃から書き続けてきた Language Server の発表をさせてもらいました。
use fields
の布教が少し出来たかも?しれないのが、一番の収穫だったかも?
もし fields (というか our %FIELDS
) の活用法に興味が湧いた方がおられたら、
昔の吉祥寺pm7 のスライドもどうぞ〜>
https://hkoba.github.io/slides/kichijojipm7/hkoba.github.io
(うぉーogを後から変えたから展開されぬ…)
謹賀新年/2019目標
明けまして、おめでとうございます
仲良くして下さった皆様、ありがとうございました。また今年もよろしくお願いします。
2018 の良かったこと
- Perl方面
- CLI_JSON を複数の業務で実戦投入して有効性を確認できたこと。 その実用性を更に向上させられたこと。
- 言語処理系勉強会 で yatt_lite の発表をさせてもらえたこと。
- Tcl/Tk方面
- tktable と tkhtml3 を fedora の copr に出せたこと。 これで yum/dnf でどこでも tkhtml3 をインストール可能になった。
- Emacs方面
- Emacs で Language Server を使うための lsp-mode に対して、それを自分流に活用するための道具 https://github.com/hkoba/emacs-on-save-jump-to-lsp-error を作れたこと (スライド)。(これで安心して typescript の開発に進める、はず…)
- Linuxデスクトップ方面
- サーバー方面
- 生活面
- ジム通いの結果、以前より体が疲れにくくなった?こと。
- 新居の生活に順応出来たこと。
2018 の反省点
- オレオレ言語の研究が完全にストップしたこと…(仕事は充実してた気がするものの、これでは本末転倒…)
- それに限らず、昨年立てた目標のうち、体力づくり位しか進展が無いこと。
- 引越し後の荷解きが、予想通り、ほとんど進まなかったこと。
- 通勤が伸びたことにより、起床が一時間早まったこと。
- 体の故障が増えてきたこと。時間もお金も掛かった上に、原因不明瞭で終わることが多いのが厳しい。けどそういう年齢よねと。
2019 の目標
perldebugger (perl -d) を楽に使うコツ的な話
この記事は Perl Advent Calendar 2018 の 12/4 の記事です
Perl Debugger
(perl -d
) を効率的に使うコツ的な話を書きます。
perl の標準デバッガなんて役に立たないと思っている人のための記事です。
TL;DR
step/next は最低限に。break したい個所が予め決まっているなら、デバッグ対象コードにダミー関数の呼び出しを加える手も有る。
Perl Debugger とは
Perl Debugger
は perl に標準で添付されたデバッガで、perl 起動時に -d
オプションを渡すことで利用できます。使い方は一般的なデバッガとよく似ていて、
l 関数名
で関数のソースを表示b 行番号
やb 関数名
で breakpoint を設定c
で実行を継続,s
で関数の中までステップ実行,n
で次の行まで実行
といった感じです。Term::ReadLine::Gnu
などをインストールすると、l
や b
で関数名のタブ補完も効くようになります。
(参考)
h
で出るヘルプ画面には沢山コマンドが並びますが、
使うコマンドはそう多くはありません。よく使うコマンドに印をつけたので
参考にどうぞ。
動的にロードされるコードに breakpoint を仕込むには
そんな Perl Debugger ですが、いざバグ取りに使おうとした時に 肝心のデバッグしたい関数に breakpoint を置けなくて困ることがあります。 この問題は、Perl がその関数が定義されているモジュールをまだ読み込んでいない時に起こります。
(一応、 b load FILE
コマンドを使えば、 require でファイルがロードされる所に breakpoint を仕込むことが出来る、らしいのですが、
FILE のパスの扱いで私は失敗してばかり…なので使わなくなってしまいました)
特に Plack や Mojolicious のようなフレームワークを用いた開発で、動的に読み込まれる .psgi ファイルやモジュールの中のコードをデバッガで調べたい場合に、 step/next を打ち続けて絶望する初心者も散見されます。
正攻法で行く場合
このように動的にロードされるコードをデバッグする場合、正攻法では動的ロードを行う側のコードの挙動を理解して、 step/next を打つ回数を減らすことが大事です。
手順としては、
- そのフレームワークがモジュールの読み込みを行う関数を探し、
- そのローダー関数に最初の breakpoint を置いて実行、
- ローダー関数に達したら、おもむろに
r
で return して自分のコードを実際に読み込ませる - その後、自分のコードに breakpoint を置く
という流れになるでしょう。以下の例は、Mojolicious から呼ばれる startup をデバッグする流れです。
逆転の発想:breakpointを置くためだけのダミー関数を使う
ただ、上記のやり方は個々のフレームワークの内部実装に対するある程度の理解が必要になるため、 準備に時間がかかりますし、正直面倒です。
それよりも、もし breakpoint を仕込みたい個所が予め決まっていて、 かつそのコードを書き換えることが可能なケースであれば、 breakpoint を置くためだけの(中身のない)ダミー関数を使う方法が有効です。
すなわち、
- ダミー関数の名前を決める(例えば main::breakpoint)
- break したい個所に、そのダミー関数への呼び出しを書き入れる(ただし注意有り)
# This method will run once at server start sub startup { my $self = shift; + + main::breakpoint(); # Load configuration from hash returned by "my_app.conf" my $config = $self->plugin('Config');
- デバッガを起動
x sub main::breakpoint {}
などしてダミー関数を定義- (予めプログラム内で定義しておいても良い)
b main::breakpoint
でダミー関数に breakpoint を設定c
でダミー関数まで飛ぶr
で該当コードに移る
この方法なら実質 c
一発で該当のダミー関数まで到達出来るため、途中のフレームワークの実装に
関する知識は実質的に不要になります。
注意点:ダミー関数を呼んだままでは本番でコケる
ただし、このままでは(ダミー関数は本番には存在しないので)、
本番で動かないコードになってしまいます。ですので、このダミー関数の存在の有無を perl の $pkg->can($methodName)
で確認してから呼ぶようにすると良いでしょう。
if (my $sub = main->can('breakpoint')) { $sub->(); }
手順としては、こんな感じです>
なお、自作のコードの場合は、ダミー関数の定義を正式なコードに予め含めておくほうが楽です。
その場合は main::breakpoint
ではなく、もっと別の名前空間に入れる方が衝突のリスクが少なくて安全です。breakpoint だけを入れたモジュール XXX::Breakpoint
みたいなものを用意しておく手も有るでしょう。
終わりに
Perl Debugger で今どきのコードをデバッグする時に困りがちな『 breakpoint を置くのが大変』問題を、breakpoint 用のダミー関数で軽減する方法について解説しました。
明日は @ytnobody さんです。
(最後しか聞けなかったけど)吉祥寺pm16感想とりいそぎ
昨夜は 吉祥寺pm#16に参加してきました。
と言っても、私は仕事のトラブルで大遅刻!
勉強会って遅刻すると、すっごく行きづらいと言うか、気持ちが落ちませんか? 私は落ちます。でも懇親会の参加者が減ると主催者さんを困らせちゃうし…と思い、会場へ。
そんな落ち気味な気持ちで会場に着き、部屋に入ると、なぜかプロジェクターでゲーム…???
#kichijojipm 起業クエストww pic.twitter.com/mUhow0FKpO
— teckl (@teckl) November 22, 2018
自作ゲームでプレゼンらしく、こりゃ凄いと思いました。
なんとかエンドロールまでいけて良かった! ありがとうございました! #kichijojipm
— :craftsman/kawasima (@kawasima) November 22, 2018
その後は休憩から LT タイム
どの LT も良かったのですが、個人的に一番刺さったのはこの LT、 スタートアップの一人技術者の立場からの採用の話でした。 曰く 『面接で高印象だった人に、お試しで働いてもらう』 作戦です。
- 転職か副業を希望している人で、面接で高印象だった人に、
- 業務委託として、お試しで働いてもらう。
- リモートワーク+週一のミーティング
昨日のLTのスライドです!遅くなりましてすみません... スタートアップで開発速度を上げるためにやった事 https://t.co/2VHdD67rSk #kichijojipm
— kakakazuma (@kakakazuma20) November 23, 2018
確かに、マッチするか否かは一緒に仕事をしてみないと分からない部分が大きいので、これは合理的だと思いました。
実際にどんな仕事をリモートワークで依頼しているのかという質問には、(Webの)フロントエンドとスマホのアプリを例に挙げておられました。確かにそれなら仕事として切り出して発注しやすそうだなと。
なお、週一のミーティングは(相手の都合に合わせるので)どうしても土日どちらかに入れることになるそう。 経営・管理側でないと出来ない技だなあと思いつつ、体調管理についてうかがうと、職住近接で8時間?睡眠を死守しているとのことでした。
たまたまその後の懇親会でもお隣の席だったので、幾つもアドバイスを頂けました。
私も(私がお客さんに提供している)技術スタックのコア部分が、自分にしか扱えない、完全なトラック係数1、SPOF になっています。ビジネスの継続性のために、この技術の継承者をどう育てるかという点が、ずっと懸案でした。
それに対して頂いたアドバイスは、ずばり、それって弟子取りですよねと。そして>
弟子を取るなら、最初の面接のハードルを上げるべしというアドバイスを頂いた。
— hkoba (@hkoba) November 22, 2018
愛すると決めてから取るべしと
相手をよく知らないまま採用して、後から相手の良い所を探しながら教育するのは、大変だから…と。
そうではなく、先に相手の中の「尊敬できる所」「愛せる所」「見どころ」を見出しておく。見いだせた人だけを、 採用する。つまり、採用する側の、「愛する覚悟」が定まった時だけ、採用するように…しないと辛いよねと。
…これは、とても響く話でした…
そうして、愛すると決めた弟子が出来たら、以外に仕事の切り出し・委譲は出来てくるものだ、という話を聞いている
— hkoba (@hkoba) November 22, 2018
上赤さん、有難うございました。