Ruby
AdventCalendar
開発環境

tappでプリントデバッグを便利に行う

More than 5 years have passed since last update.

こんな経験はありませんか?

アプリケーションの開発中は少なからずプリントデバッグを行うことがあると思います。そのなかで、以下のような経験はありませんか?

  • ArrayやHashのメソッドチェーンの間のオブジェクトの状態を確認するために、一時変数を用紙したことがある
  • ppやpを消し忘れてリポジトリにコミットしてしまったことがある

以上の経験を一度でもしたことのある方は、いますぐtappを導入すべきです。

tappとは

tappは、プリントデバッグを簡単に行うためのライブラリです。tappをrequireすると以下のメソッドが使えるようになります。

  • Object#tapp
  • Object#taputs

動作はいたって単純で、レシーバをpp(puts)して返すというだけです。

>> require 'tapp'
=> true
>> "hoge".tapp
hoge
=> "hoge"

なぜこれが便利なのか

プリントデバッグするのにソースコードの変更が最小で済む

前述のような単純な文字列を出力する場合には、pppと大差ありませんが、すこし複雑になるとその差は歴然です。

例えば、「1から10までの数字で奇数だけを合計する」ような処理では、tappを使って次のようにメソッドチェーンの途中の状態を見ることができます。

>> (1..10).tapp.select(&:odd?).tapp.inject(&:+)
1..10
[1, 3, 5, 7, 9]
=> 25

これと同じことをpppでやろうとすると、出力したい箇所を一時変数に入れなければならず、非常に面倒です。

また、Symbol#to_procと組み合わせることで、属性やメソッドの返り値を確認するのにも使えます。

> array = [1, 2, 3, 4, 5].tapp(&:size)
5
 => [1, 2, 3, 4, 5] 

プリントデバッグを仕込んだままコミットするのを防ぐ & 発見しやすくする

pppを使わないようにし、ソースコード管理をgitで行っている場合はtapp grepコマンドが便利です。

tapp grepコマンドは、tappで提供しているメソッドを全て検索してくれるので、消し忘れやの防止や、発見に非常に役立ちます。

$ bundle exec tapp grep
app/controllers/application_controller.rb:    @current_user ||= User.find_by_id(session[:user_id].taputs) if session[:user_id].present?
app/controllers/application_controller.rb:    !!current_user.tapp

Railsで使うときは注意も必要

Rails(ActiveModel)でtappを使う際には、AssociationProxyやScopeに注意しなければいけません。

普通に使っている分にはArrayのように見える彼等ですが、チェーンの間にtappを差しこんでしまうとそこでチェーンが切れてしまうため、その先がエラーになってしまう場合があります。

どこまでがScopeやAssociationProxyのチェーンになっているか見極めてtappを差し込みましょう。

おわりに

もし、現在pppを使ってプリントデバッグをしているようでしたら、今すぐにでもtappを使うべきです。まずはGemfileにgem 'tapp'を加えてみましょう。(Railsでしたら、developmenとtestグループに足しておくのがおすすめです)

また、Version 1.4.0からデフォルトprinterの変更や、callerを出力するかどうかを設定できるようにもなっていますので、興味のある方はぜひREADMEtappのacceptance testをご覧ください。

tappはオープンソースプロダクトです

tappはオープンソースプロダクトです。みなさんからのpull requestをお待ちしています!

esminc / tapp