パッケージの作り方

次に、どうやってパッケージを作っているのかについてです。パッケージはすべてGitHubで公開しています。

ローカルだけのものもあるっちゃありますけど、基本的に研究関係のものだけです。みんなに使ってもらいたいと思っているものは全部GitHubに公開していて、変更はすべてpull requestフェーズでやっています。masterに直接pushしたりはしません。

Travis CIとかAppveyorみたいな、継続的インテグレーションを実行していて、pull requestか、この継続的インテグレーションのチェックに通ったらマージするという、標準的な開発スタイルですね。Juliaの本体と同じ開発スタイルを取っています。

Document.jlというものを使って文書を作成したり、attobotっていうGitHub上のbotを使って、簡単にパッケージのデプロイができるようになっています。公開、バージョンを付けてみんなに使ってもらうための準備は、attobotでやっています。

こうやって、自分で使いたいパッケージはすべて公式パッケージにしています。現在はMETADATA.jlに登録されているものが公式パッケージなんですが、attobotを使ってMETADATA.jlに対して公開しています。Julia 1.0から、METADATA.jlが新しいシステムに変わるはずなんですけど、まだ移行が完全じゃなくて、こっちを半分引きずってるようなシステムになっています。

すべてのパッケージに関して、pull request、feature requestなど、Issueとかやってもらうのは、ぜんぜん歓迎しています。ありがたいことにけっこう、週に1、2個ぐらい、pull requestをいただいてます。いま忙しくて、対応できてなくてごめんなさい。

開発スタイル

開発スタイルとしては、使ってるツールは本当に標準的なものですね。

julia、vim、tmux、git、あとdirenvという、環境変数なんかをプロジェクトごとに設定できるツールです。最近知ったんですけど、これすごく便利です。

ホームディレクトリ以下のworkspaceというところにJuliaのパッケージがたくさん、gitのレポジトリとして直接置いてあって、その開発用の環境も、direnvとかで調整しています。

他人のパッケージにpull requestを送るときも、まずこのホーム以下のworkspaceに1回gitをクローンして、そこでpatchを作ります。それでpull requestをGitHub上で投げます。

Juliaのパッケージは基本的にどれもGitHubを使って開発してるので、pull requestとかを送りたい場合はgitを使いますね。変更を送りたい場合は、GitHubのpull requestを使うということです。

Julia 1.0からパッケージマネージャーが第3世代になりまして、これが非常に便利です。例えば、これを使ってパッケージモードというので、これのパッケージモードに入ってテストを実行するとかっていうことが、ワンコマンドで簡単にできたり、依存パッケージの管理なども、全体に影響を与えないように行うことができます。

例えば、メインでやってる研究開発とかの仕事があって、そっちの環境を壊したくないときに、このへんのパッケージマネージャーを使うと、パッケージローカルの依存関係とかも管理できます。ユーザーの全体の環境には影響を与えず、パッケージごとに依存管理をする感じですね。なので、このへんを使ってパッケージの管理をしています。

あと、これ、みなさんあんまり知らないと思うんですけど、Revise.jlという、ちょっとダメージを受けるパッケージ名なんですけども、Juliaを再起動せずにパッケージのコードを更新できるパッケージが非常に便利です。

どういうことかというと、これを最初に読み込んでおくと、ファイルの変更をトラックしてくれて、変更があったらパッケージを勝手に読み込んでくれるんですね。そうすると、Juliaを再起動せずにパッケージのコードが更新できます。

なので、いったんこちらのほうでRevise.jlを読み込んでおいて、開発したいパッケージを読み込むと、パッケージのコードに変更を加えたときに、結果がすぐに反映されるので、どんどんどんどん開発を進められます。いちいちJuliaを再起動しなくていいということですね。本当に、これがないと死んじゃうようなパッケージです。

どうやって覇権を取るか?

ここから、覇権の取り方の説明です。

「そもそも覇権が取れてるのか?」という話ですけど、ニッチには取れてると思います。非常に狭い分野ですが。例えばEzXML.jlとTranscodingStreams.jl、この両方のパッケージは、毎月数万はダウンロードされています。

Julia 0.6まではGitHubから直接クローンしてたので、ダウンロード数が直接観測できたんですけど、1.0に変わってからそれができなくなったので、正確な値はわかんないですが。0.6の時点で毎月数万ダウンロードされてたので、いまもほとんど変わらないはずです。

GitHubのスター数に関しても、既存のパッケージより多くなっています。他のもの、既存のものに替わって、私の作っているものが使われ始めているということです。

ということで、どうやって覇権を取るかなんですけど、基本的には、既存パッケージの問題を解決することが必要です。使ってみて、問題を挙げて、解決するというサイクルを1万回繰り返すと、良いパッケージができるということですね。

だいたいどんなパッケージでも、使ってみると不満があって「こうしたほうがいいんじゃないか」とデザインの案が出てくると思うので、それを実現する。ほぼそれだけです。

どういう問題があるかを、具体的に、例えば星取表とか、箇条書きしてみて「(既存パッケージには)こういう問題があって、(新しく作った)このパッケージはこれを解決する」ということが主張できると、既存のパッケージを上回るスター数になる、より使われると思います。

それができたら、各所でアピールすることが必要です。これも非常に重要です。これを使って、(問題)解決してGitHubに上げただけでは、たぶん誰も使ってくれない。いろんなところでアピールしなきゃいけないと思います。

覇権を取るための戦略

どうアピールしていくかというと、Discourseでアナウンスをすることが、いま一番たぶん重要ですかね。

Discourseというのは、Juliaのユーザーが集まっているフォーラムです。「Julia Discourse」とかでググってもらえば、どういうところかわかると思います。メーリングリストみたいなものがスレッドになっていて、トピックごとに話していくようなWebサイトです。

例えば、EzXML.jlをリリースしたときに「EzXML.jlをリリースしました」って書いて、投稿をするということですね。簡単な使い方とか、なんで作ったのかとか、あるいはコード例とかを示して「こんなパッケージを作ったので、ぜひみなさん使ってください」「意見をください」ってアピールする。

TranscodingStreams.jlの場合も同じですね。TranscodingStreams.jlっていうパッケージを作りました、こういうパッケージですと簡単に書いて、説明とか、詳しい使い方、コンセプトなどをDiscourse上で説明します。

Juliaをメインで使ってる人たちは、1日1回ぐらいはDiscourseを見てる人が多いと思うので、ここでアピールすると「なるほど。こういう新しいパッケージができて、既存の問題が解決されたんだ。じゃあ、こっちに移行してみようかな」という動機になると思います。

次に、GitHub映えですね。これは非常に重要だと思っています。

みなさんもたぶん経験があると思います。「なんかパッケージがあるらしい」「ライブラリがあるらしい」ってGitHubのWebサイトに行ってみて、readmeに何も書かれてなかったり、一言だけだったりすると、そのパッケージを使う気があんまり起きませんよね。なので、GitHub映えは覇権を取るために非常に重要だと私は思っています。

(スライドを指して)左はreadmeのスクリーンショットです。EzXML.jlというロゴをわざわざデザインして、パッケージの説明を書いて、どういうところが優れているかを書いています。

あと、Document.jlへのリンクとか、あるいは、Travis CIとかAppveyorとかで、継続的インテグレーションをしていることを示してますね。コードのカバレッジとかも、ここに書いてあります。ちゃんとメンテナンスされていて、ヘルシーな状態のコードだということを主張するために、こういうバッチを付けています。

こっちはTranscodingStreams.jl(のreadme)で、さっき見せたこのコンセプトの絵みたいなものを簡単に書いて、特徴と、インストールの仕方と、使い方を載せています。標準的な方法ではありますけど、これがないとなかなか使ってもらえない。GitHub映えさせるために、こういうところに気を付けてreadmeを書くといいかなと思っています。

あとは、手厚いサポートですね。

EzXML.jlのときに、使ってくれた人からIssueが届いて「こういうふうにやったらエラーとか問題が起きた」って言われたことがあった。そういうときに、ちゃんと解決すること。当然というか、やるべきことなんですけど、見逃さないでちゃんとやることが重要かなと思ってます。

最終的に「解決したから新しいバージョンを使ってね」って言ったら「Awesome, thanks!」って言ってくれて、この人はまた別のプロジェクトでも、このパッケージを使ってくれるだろうなと。

あるいはDiscourseで自分のパッケージが言及されて、「どうやって使うのかわかんない」「問題が起きた」って言ってる人がいたら、それをうまくとらえる。

エゴサというか、パッケージ名でググってみたり、あるいはgzipとか、自分のパッケージに関連するキーワードでDiscourseを検索してみて、なにか質問してる人がいたら回答してあげるということですね。

そうやって手厚くサポートしてあげると、いったん興味を持ってくれた人を逃さない。そういう意味で、サポートは重要だと思っています。

あと、ちょっとアレですけど、既存のパッケージを使っているパッケージにpull requestを送るっていう技もあります。もうすでに他のパッケージを使ってるんだけど「俺のパッケージのほうがすばらしいからこっちに変えろ」っていうpull requestを送る。

(会場笑)

もちろん向こうも公平な目で見ますから「新しい奴が変なもん送ってきた」みたいな感じなんですけど、どっちにするかの判断は向こうの人に任せるとしても、基本的にだいたい取り込んでもらえる。新しいのもいけますよって感じです。なんでそこまでやるのかわかんないですけど、そんな感じでやってます。

パッケージを1つ作ってみよう

まとめです。

Juliaのパッケージは、まだまだ必要です。1.0になって全部パッケージがそろったというわけではなく、これからもどんどん新しいものが必要になります。まだいろいろサポートしきれてない部分がたくさんあると思うので、ぜひ探してみてください。

このたび、めでたくJulia 1.0になったので、最新版への追従がすごく簡単になるはずです。私がパッケージの開発を始めた頃はJulia 0.2とかで、0.1上がるごとに泣きながら修正したりしてたんですけど、APIは基本的に安定しましたから、バグとかに依存しないかぎりは、ドラスティックなAPIの変更はJulia本体にはないはずです。

パッケージを作る時には、必ずGitHubを使ってください。Juliaを使ってる人たちは、ほとんどGitHubしか見ないので。他のところに置いて、インストールとかする方法もあると思いますけど、あんまり使われないので、基本的にはGitHubに置いておく。宗教上の問題とかがなければ、GitHubを使えばいいと思います。あと、Revise.jlは非常に便利です。これは絶対に覚えて帰ってください。

あとは、しつこくアピールすることですね。先ほども言ったように、まずDiscourseでアナウンスする。Issueとかpull requestが来たら、ちゃんと対応する。あと、GitHub映えを意識して、readmeをきれいに、ちゃんと書くことが重要です。

という感じなので、とりあえずぜひ、重要なパッケージを1つ作ってみましょう。簡単なので、ドキュメントを読めばわかると思いますが、もしわからないことがあれば私とかに聞いていただければ、重要なパッケージの作り方を指南しますので、みなさん、自分で「ほしいな」と思ったパッケージを作ってみたらいいと思います。以上です。ありがとうございました。

何かご質問などある方いらっしゃいますか?

(会場挙手)

質問者1:最初、パッケージを自分で作って、METADATA.jlに載せるか載せないか悩むことがあると思うんですけど、そのときってどういうふうに判断しますか?

bicycle1885:あー、載せるか載せないか。そうですね。基本的に公共性があるかないかみたいな話だと思うんですけど(笑)、絶対自分しか使わないようなパッケージは置いてないです。研究用のものも、いまのところ置いてません。

Juliaのパッケージのコミュニティに入れたいパッケージは、置くようにしてます。むしろ、自分で使いたいもの、例えばgzipとかXMLとかは自分で使うので、自分でそれに依存したパッケージを作る可能性がある。

そうすると、METADATA.jlに置いとかないと依存関係として書けないので、基本的に自分が依存関係に置きたいなと思ったパッケージは、METADATA.jlに登録するようにしています。

司会者:他、質問ありますか? 大丈夫ですかね。それでは、佐藤さん、ありがとうございました。

bicycle1885:ありがとうございました。

(会場拍手)