こころがホッコリー

ただイカしたRubyistになりたい人生だった。

Rubyで alias method をチェーンしてフックメソッドを書いてみた(※ ActiveSupport未使用)

しばらくブログを書いていませんでした。 まず最初に近況を3行で書きます。

  • 某TDDBCに参加し、TDD力を付与してもらいました
  • mbed祭りで登壇しました
  • Railsエンジニアになって半年が経ちました

転職して半年経って思うことは、別エントリーで書きます。

Rubyで alias method をチェーンしてフックメソッドを書いてみた

本題です。

実システム運用における使われないメソッド

Ruby(Rails)で実際に使われるシステムを開発をしていて、
「このメソッド、消せると思うんだけど、確信が持てないんだよな〜......」
というのは、よくあるシチュエーションではないでしょうか?

C++のような静的型付け言語では、そのようなメソッドコンパイラが検知してくれるので、気にする必要はありません。
動的型付け言語である Ruby は、このような悩みには目を瞑るしかないのでしょうか? 地道にgrepと目視レビューをしていくしかないのでしょうか?
このあるあるについて、クラウドワークス社のブログで、「方法3. 未使用な何かの削除」として触れられています。

engineer.crowdworks.jp

上記記事では、ActiveSupportalias_method_chain を用いて、任意のメソッドが呼ばれた際にロギングする仕組みを実現しています。
本記事では敢えて、というよりも私の知識不足により、ActiveSupportに頼らずにフックメソッドの実現に挑戦してみます。(alias_methodを駆使しているので、発想的にはalias_method_chainと同じかと思います)

コード

本コードの作成にあたって、下記の記事を参考にさせていただいています。
Ruby でメソッド呼び出しのフック処理を実行する - blog.kymmt.com
Rubyでメソッドの呼び出し直後と終了直後をhookしてログを出力したい - miyohide's blog

実行結果

✗ ruby define_hook_method.rb
hello, world
hook message
foobar
hook message
bar
hook message

既にあるコードを参考にしてとはいえ、初めてメタプログラミングを自分で書きました。

補足

今回の方法はフックメソッドを指定したいクラス内で、モジュールのincludeを必要とする手間があります。
実はActiveSupportを用いると、今回のやり方よりも、もっとスマートに、かつモジュールincludeのコードが不要でやりたいことを実現することができます。
そのコードは、作者が私ではないので本記事では触れませんが、興味のある方は prepentedprepend あたりを使って検討してみてください。