Rubyで書かれた設定ファイルから雑に取り出す


この記事は

表参道.rb #29 ~ Module ~ におけるLT発表資料です hask(_ _)eller


自己紹介

  • 山本悠滋 (@igrep)
  • Haskell歴 ≅ プリキュア歴 ≅ 社会人歴 ≅ 約5年半。
  • 仕事はJavaじゃば!
  • 前職はSansanで、EightのバックエンドをRailsで書いておりました。
    • なので私がいた時代の話ならあんなこともこんなことも話せちゃうよ!

軽い宣伝

  • Haskellでリッチな静的型付けの世界にハマりましょう!
  • Haskell-jpというコミュニティーグループで、Slack Workspaceなどを運営しています。

Vagrantめんどい

  • チームで使っているVagrant boxとVagrantfileがあった。
  • 一方自分には丹精込めて育てている、Vagrantで管理されてないVMがあった。
  • けちんぼなんでVMをいくつも作るのはいやだった。
    • Dockerにすれば大体解決する話なんですが、ちょっと大人の事情で...。

そこで!

  • Vagrantfileから、port forwardingの設定など、必要な部分だけ取り出すスクリプトを書こう
    • Vagrantが何をしているか詳しく知る必要がない
    • 取り出したら後はVBoxManageコマンドなどを適当に呼んで、丹精込めたVMに、Vagrantfileに書いた設定を適用!

作った その1

vagrant2vboxmanage


作った その1: ソース抜粋

module Vagrant
  def self.configure(*args, &block)
    @config = Config.new
    block.call @config
  end

  class Config < ::OpenStruct
    ...
  end
end

作った その1: 仕組み

  • Vagrantという名前の、各メソッドが受け取った引数だけを記録する偽物の クラス モジュールを作った
  • 本物のVagrantは一切ロードしない
  • 偽物のVagrantを定義した状態でload './Vagrantfile' する。

.oO(待てよ?)

これはいろいろ動的にできちゃうRubyのことだ、method_missingを使えばもっと楽ができたんじゃないか...?


作った その2

spy-void


作った その2: 詳細な動作

みんな大好きmethod_missingを使い、

  • 任意のメソッドに対して引数とメソッド名を記録する
  • 戻り値はすべてself(続けて呼び出したメソッドもすべて記録しちゃう)
  • ブロックが渡された場合は、ブロックが必要とする引数の数だけselfを渡して呼ぶ

作った その2: 詳細な動作

最終的に記録したメソッドを取り出すときは

SpyVoid.retrieve_log(Vagrant)

記録したメソッドがキーで、渡された引数の記録が値のOpenStructが返る


作った その2: 詳細な動作

  • 後はOpenStructをいじって好きにしよう!
  • Hashieとかもっと良さそうなやつがあるのは知ってるけど、所詮雑なものなので!

作った その2: ちなみに

やっていることがTest Spyとよく似ていたため、「Spy Void」と名付けました。

そのままSpyとして使うのも悪くないかも。


あしからず vim(_ _)mer

  • 書き捨て用に作ったものだし、普段Rubyを使うこともなくなったのでrubygemsには上げません!
    • コピペして適宜書き換えて使うのでも十分便利だと思う。
    • ライセンスはMITにしとくので、やりたくなったら勝手にやっちゃって!

まとめ

  • method_missingたのしい!