概要
下記のようなコードで foo
の戻り値をログ出力する際、どうしてますか?
def foo(opts)
if opts
"BAR"
else
"FOO"
end
end
こうやってローカル変数を使って出力していた時期がありました
def foo(opts)
r = if opts
"BAR"
else
"FOO"
end
p r
r
end
いまわかってるのは3つの方法
Object#tap
- tapp (gem)
Object#display
Object#tapでローカル変数を排除する
結論、こんな感じに書き換えできます
def foo(opts)
if opts
"BAR"
else
"FOO"
end.tap{|r| p r}
end
if..endの末尾に .tap{|r| p r}
を加えるだけ
これで動く理由は参考資料でご確認ください(まるなげ
tapp (gem)なるもの
コメントで tapp を紹介いただきました (thx! yancya)
require "tapp"
def foo(opts)
if opts
"BAR"
else
"FOO"
end.tapp
end
まさにこれ。
Object#display
なるもの
コメントで Object#display
を紹介いただきました (thx! riocampos)
def foo(opts)
if opts
"BAR"
else
"FOO"
end.display
end
標準メソッドにこんなものがあったとはっっ!
使い分け
-
Object#tap
: Loggerで出力するとき。わりと本番用? - tapp (gem): ともかく仕掛けておいて、あとで全部削除したいとき。grepしやすい
-
Object#display
: 出力先を一時的にfileにするとか、手軽に変えられるようにしたいとき
Object#tap
はロギングが要件に組み込まれてる時にも使えます
require "logger"
$logger = Logger.new($stderr)
$logger.level = :debug
def foo(opts)
if opts
"BAR"
else
"FOO"
end.tap{|v| $logger.debug v}
end
foo(true)
#=> D, [2016-04-08T08:00:45.572860 #13340] DEBUG -- : BAR
Object#display
は標準出力とかに出しにくいバイナリデータを出力するのに良さそうです
$to_file = open(Time.now.to_i.to_s, "wb")
def foo(opts)
if opts
"BAR"
else
"FOO"
end.display($to_file)
end
foo(true)
#=> UNIXタイムなファイルが作成され、中身はBAR
参考資料
あとがき
Qiitaのエントリーに対する、具体的なユースケースという名のパクりエントリーでした、ごめんなさい
あと、エントリー名を "tapかわいいよ、tap" にしようとおもったら、完全に一致するブログがあったので変更