$shibayu36->blog;

クラスター株式会社のソフトウェアエンジニアです。エンジニアリングや読書などについて書いています。

「Cartonの内部」について社内勉強会で発表した

Perlのバージョン管理ツールであるCartonの内部について、社内勉強会で発表したので、その時の資料をそのまま公開する。けっこう雑に作ってしまったので、正確性については保証できないけど、Cartonのソースコードリーディングの際の参考になればと思う。

アジェンダ

  • Cartonとは
  • いろいろトラブル
  • carton installの挙動を理解する

Cartonとは

  • Perlのモジュール管理ツール
  • 依存モジュールを特定のバージョンに固定して、インストールしてくれる

Cartonとは(深堀)

  • 一番重要なのはcarton install
  • 基本的にはcpanmのラッパーとしてcarton installが実現
  • Module::CPANfileなど、小さいモジュールを組み合わせている

いろいろトラブルもある

  • cpanfile.snapshotが環境によって変わる
  • carton install --deploymentでインストール出来ないものがあり失敗
  • carton installの挙動を理解すると、大体なんでそういうことが起こるかわかるので紹介

carton installの登場人物

  • cpanm
  • cpanfile
    • 依存モジュールを書くファイル
  • cpanfile.snapshot
    • cartonのバージョン固定用ファイル
  • 02packages.details.txt.gz
    • CPANにおけるインデックスファイル
    • モジュールをインストールするために、どこからダウンロードすればいいか記述
  • install.json MYMETA.json
    • あるモジュールのメタ情報が記述
    • 現在のversion, 依存モジュール
    • cpanmがモジュールインストール後に作る

carton installがやっていること

  • バージョン固定のためのファイルを生成(02packages.details.txt.gz)
  • cpanmでインストール
  • cpanfile.snapshotを生成(install.json, MYMETA.jsonを利用)

バージョン固定のためのファイルを生成

  • cpanfile.snapshotからCPANのインデックスファイルを生成
    • 02packages.details.txt
  • 02packages.details.txtには、モジュール名、version、ダウンロード元が記述
  • cpanmがあるモジュールはどのversionをどこからインストールすればいいか分かる
Apache::LogFormat::Compiler 0.32                   K/KA/KAZEBURO/Apache-LogFormat-Compiler-0.32.tar.gz
Attribute::Params::Validate 1.18                   D/DR/DROLSKY/Params-Validate-1.18.tar.gz
Class::Inspector       1.28                   A/AD/ADAMK/Class-Inspector-1.28.tar.gz
Class::Inspector::Functions 1.28                   A/AD/ADAMK/Class-Inspector-1.28.tar.gz
Class::Singleton       1.5                    S/SH/SHAY/Class-Singleton-1.5.tar.gz
DateTime               1.18                   D/DR/DROLSKY/DateTime-1.18.tar.gz
DateTime::Duration     1.18                   D/DR/DROLSKY/DateTime-1.18.tar.gz
DateTime::Helpers      1.18                   D/DR/DROLSKY/DateTime-1.18.tar.gz
DateTime::Infinite     1.18                   D/DR/DROLSKY/DateTime-1.18.tar.gz
DateTime::Infinite::Future 1.18                   D/DR/DROLSKY/DateTime-1.18.tar.gz
DateTime::Infinite::Past 1.18                   D/DR/DROLSKY/DateTime-1.18.tar.gz

cpanmでインストール

  • cpanfileを使って依存モジュールを知る
  • 02packages.details.txtを使って、どのバージョンをインストールするか知る

発行されるコマンド

  • 以下の様なコマンドが発行される
cpanm -L local --mirror http://cpan.metacpan.org/ --mirror http://backpan.perl.org/ --mirror-index local/cache/modules/02packages.details.txt --cascade-search --save-dists local/cache --cpanfile cpanfile --installdeps .
  • -L local
    • local以下にインストール
  • --mirror http://cpan.metacpan.org/ --mirror http://backpan.perl.org/ --mirror-index local/cache/modules/02packages.details.txt --cascade-search
    • 02packages.details.txtのindexでインストール、そこに存在しなかったらmetacpanやbackpanにfallback
  • --save-dists local/cache
    • モジュールのtarはlocal/cacheに保存する
  • --cpanfile cpanfile
    • cpanfileの指定

cpanm内での挙動

  • cpanfileを見ながら、依存モジュールを走査
  • あるモジュールをインストールする
    • そのモジュールのどのバージョンをインストールするかは02packages.details.txtをみて決める
    • cpanfile.snapshot -> 02packages.details.txtなので、cpanfile.snapshotに記述されたバージョンが入る
    • 02packages.details.txtに存在しない -> 他のmirrorにfallbackされ、インストールされる
  • モジュールの依存がすべて解決されるまで、これを繰り返す

cpanfile.snapshotを生成する

  • 依存モジュールはすべてlocal/以下に入ってる
  • local/以下のinstall.jsonとMYMETA.jsonをすべて取ってきて、cpanfile.snapshot作る
    • local/lib/perl5/(archname)/.meta/ 以下のディレクトリに、それぞれのdistのinstall.jsonとMYMETA.jsonが保存されている
      • 例) local/lib/perl5/darwin-2level/.meta/Algorithm-Diff-1.1902/{install|MYMETA}.json
      • この中にはモジュールのversion情報やさらなる依存情報が入ってる

なぜ問題が起こるか

  • cpanfile.snapshotが環境によって変わる
  • carton install --deploymentでインストール出来ないものがあり失敗

cpanfile.snapshotが環境によって変わる

  • local/以下にインストールされているモジュールをすべて見るため
    • local/以下に手動でモジュール入れたらおかしくなる
    • 一回cpanfileに依存を増やした後、消してもlocalからは消えないので残る
    • rm -rf local/ して再インストールしないとおかしくなる...
  • MYMETA.jsonを参考にするが、動的に依存を変えるモジュールによって、環境によって違うMYMETA.jsonが作成される
    • Macの場合とLinuxの場合で依存モジュールを変えるモジュールは、MYMETA.jsonが環境によって変わる
    • cpanfile.snapshotはそれを参考にするので、変わる

carton install --deploymentでインストール出来ないものがあり失敗

  • carton install --deploymentは02packages.details.txtだけを見て、metacpanにfallbackしないモード
  • 環境によってミスったcpanfile.snapshotが作られていると死ぬ
    • 02packages.details.txtに必要なモジュールが含まれていないため

結論

  • モジュールのインストールはcpanmがやっている
    • うまく02packages.details.txtを作って、cpanmをだますことで、バージョン固定
  • cartonはcpanfile.snapshotからCPANのインデックスを作るのと、cpanfile.snapshotを作るだけ

他のパッケージ管理ツールは?

  • bundler
  • npm
  • etc

bundler

  • 基本はglobalに全部モジュール入れる、bundle exec時にPATHの通し方を工夫する
    • 同じモジュール入っていたら無視できるのでインストール速い
  • Gemfile.lockは毎回Gemfileから依存をたどって作り直す(local/から全部ではない)
  • gemに依存を全部取ってくるAPIがあって、そこから環境依存のものも全部取ってきてるっぽい(?)
    • cpanfile.snapshot, Gemfile.lockには依存が多く記述されるのは問題ないため

carmel

  • bundlerっぽい動き方を目指している
  • 5分くらい使ってみたけどなんかうまく動かなかった

参考資料

「敗者のゲーム」読んだ

投資を勉強シリーズで「敗者のゲーム」を読んだ。第6版が直前に出てたので、ミスって第5版買ってしまった。

この本は、過去の市場の統計情報に基づいて、市場原理について教えてくれる本。この本を読んでも、資産運用の実際の方法を学ぶことは出来ないが、他の本がなぜその資産運用の方法を提案しているのか、他の本は本当に正しいのかを判断するための基礎知識を学ぶことができる。読むのは少し時間がかかるが、非常にためになる本だった。

いつもどおり心に残った部分をまとめていく。

  • 市場の成長率には殆ど勝てない
  • リスク許容度と資産配分
  • 一般的に投資家はバックミラーを見て運転する

市場の成長率には殆ど勝てない

この本によると、投資家は市場の成長率に勝とうとするが、これまでの歴史を振り返るとほとんどの投資家(長い目で見ると75%以上)は市場の成長に打ち勝つような運用はできていないらしい。また、投資家の90%以上はプロであることを考えると、個人投資家は市場の平均にかつような運用は殆どできないと考えられる。それは個人の投資家では企業と比べて情報量やノウハウが全然違ってしまうためだ。

市場の成長率に殆ど勝てないのであれば、個人投資家は長期投資の目的やリスク許容度をきちんと決め、市場の成長率に準ずるように分散投資するのが良いとされている。つまりポートフォリオを決めた上でインデックスファンドを利用することを薦めている。

このことは非常に納得できた。そもそも統計的に半分以上が負けるなら、個人でかつ専門ではない分野で勝てると思わないようにしたい。

リスク許容度と資産配分

個人で資産運用をする際に考える重要な項目は「リスク」であると書かれていた。では「リスク」とは何か。

リスクとはこの本の中では以下のように書かれている。

リスクの本質的な意味は単純である。資金が本当に必要な時に、手元に存在しないことだ

またこのリスクを考えた上で、リスク許容度とは「市場の極端な暴落期において、どこまで耐えられるか」を考えると良いとされている。つまり資金が本当に必要な時に市場が大暴落していたとしても、必要な資金は得られるというのを最低条件として、リスク許容度を決めていくと良いのだろう。

リスク許容度が決まると、それに従った資産配分が決まってくる。株式と債権とキャッシュの比率などを決められる。ちなみに一番最小のコストで、運用成績に一番最大の効果を出すのは、株式・債権等の資産配分比率の策定の段階であると書かれているので、資産配分の比率を決めるのは大切である。


上記のように考えると、資産運用をどのように考えるか少しずつ見えてくる。

まずは「資金が本当に必要な時」はいつかを考えておくことが重要そうだ。生きている中で、平均的な生涯の必要資金や、大きい支出がいつ発生するかなどをある程度調べておくと良さそうに見える。

大きな支出が発生したときにどのくらい資金があれば良いかさえ分かれば、どこまでをリスク資産にふっても良いかなどが見えてくる。そうすれば株式にどのくらい、債権にどのくらいなどといった資産配分比率が決まってくるということのようだ。


そうはいっても、資産運用を始めたことがないうちから、ポートフォリオをきちんと決めるのは難しいなとも思った。なので、最初は他の本に書かれているような商品を利用して資産運用を始めてみて、一年くらいの頻度でポートフォリオの設計がこれでいいのかというのを見直すというようにしていきたいと感じた。

一般的に投資家はバックミラーを見て運転する

この本の中に、

一般的に投資家は、バックミラーを見て運転するように、上げ相場ではさらに上昇を見込み、下げ相場ではさらなる下落の力が働くと考えがちだ

と書かれている。自分でちょっとだけ商品を買ってみると、確かに最初は数百円の変化でも気になったりするので、これが大高騰時や大暴落時にはパニック的にそういうふうに考えてしまうのだろうと思った。

実際には平均への回帰という原則が働くので、平均から離れるほど平均へ戻っていく。つまり上がれば上がるほど下がる力が強くなるし、下がれば下がるほど上がる力が強くなる。そうすると、平均より下がっているときはむしろ買ったほうが良く、平均より上がっているときはむしろ売ったほうが良いのだが、投資家はその逆を行ってしまう。

きちんとしたポートフォリオ設計をせずに、相場の上がり下がりに一喜一憂しているとこのような考え方に縛られてしまうことになる。パニックにならないためにも、ポートフォリオ設計をきちんとして、徐々に積み立てていくという戦略をとっていきたい。

まとめ

投資の勉強をするために、「敗者のゲーム」を読んだ。この本から得た知識を元に、市場の変化や周りの意見にあまり惑わされずに資産運用をできたらなと思う。

この本で言及されていた「ウォール街のランダムウォーカー」も気になったので読んでみたい。