この記事はPerl6 Advent Calendar2016の21日目の記事です。
昨日は、titsukiさんによる「NativeCallを使ったプログラムの一部だけを最小構成で再現する方法」でした。
こんにちは、吉祥寺.pmというイベントをやっているMagnolia Kです。
Perl6がリリース(と言っていいのか微妙ですが)されてから1年経ちました。皆さん、使っていますか?自分は使っていません!
1年ぶりにまた触ってみようかな、と思ったので以前調べたこと整理して書いてみます。
Perl6の実装を追いかける
去年の年末に比べると実装がガラっと変わることも減ってきたPerl6ですが、2015年後半の怒濤の実装変更はもの凄いものが有り、いままで動いていたコードが突然動かなくなること多々有りました。最近は落ち着いてきたとはいえ、やはり慣れない言語を使い始めるときには、実装を追いかける方法を知っておいた方がいいですね。
file-watch関数の実装を追いかける
ここではPerl6のコアモジュールであるIO::Notification
のfile-watch
という関数を例に実装方法の追いかけ方を紹介します。
file-watch
は、Perl5でいうところのFilesys::Notify::Simple
みたいなやつで、監視対象のファイルがアップデートされたら指定したコードがキックされる、というものです。
Perl6(Rakudo)のコードはGitHub上で管理されていますので、まずはGitHubに置かれているコードを見てみましょう。
コアモジュールは、src/core/
配下に配置されています。ダブルコロンをパスの区切りに置き換えてモジュールが配置されているのもPerl5と同じです。
https://github.com/rakudo/rakudo/blob/nom/src/core/IO/Notification.pm
わずか31行のコード、一つしか関数が定義されていないので、すぐに読めると思いますが、単にnqp::watchfile
を呼び出して、Supplyを返しているのが分かりますね。
IO::Notification
のドキュメントには、短いですがサンプルコードが用意されているので、そちらと併せて読むとすぐに理解できるでしょう。
nqpとは?
さて、ここからが本題です。
先ほどのソースコードを見ると分かると思いますが、実装の実態はnqp::watchfile
という箇所です。このnqp
とは何でしょうか?
正体は、このリポジトリのコードです。
nqpは、'not quite perl'の略とされていて、Perl6を実装するためのPerl6のサブセットを提供します。ややこしいですね。
Perl6はMoar VMや、JVM(Java Virtual Machine)といった複数の環境で動作することを目指して作られており、それらの実行環境の差分を吸収するのが、nqpという仕組みになっています。
例えばjvm用のwatchfileメソッドは、こちらで定義されていて、実装されていない(!)ことが分かります。
実際にjvm版を実行しようとしたのですが、2016.12.19現在、なぜかmacOS上ではビルドが通らないので、それはまた今度…
一方でmoarVM用のwatchfileメソッドは、こちらで実装されていることが分かります。
これでwatch-file関数の実装が分かりましたね!(名前が逆転する理由は分かりませんでしたが…)。
おわりに
Perl6では、実装がRakudo -> nqp -> moarVM or jvmと多段階になっていて、なかなか追いかけづらい構成になっていますが、一つの関数やメソッドに絞って追いかけて行ったり、grep等を上手く使って丹念に見ていけば大丈夫です(というほど追いかけていないですが)。
明日は、titsukiさんです!