こんにちは.fukuoka.exという技術コミュティにて活動しております、twibeeことenpedasiと申します。
今回は、変数の状態をファイルに書き出す方法をご紹介します。
私自信が開発中に巨大なMapをデバッグするのに困っていたので、ここでご紹介致します。
結論
忙しい時に見ると思うので、結論から先に書きます。
File.write! "debug.txt", inspect(val, [pretty: true, limit: :infinity, printable_limit: :infinity])
valが変数とした場合に、内容をdebug.txt
に書き込む例です。
下記のようにモジュール化してLib直下などに配置しておくと良いでしょう。(一桁の数字のリストが化けないような設定も追加してあります)
defmodule Deb do
def put(val, file_path \\ "debug.txt") do
File.write! file_path,
inspect(val, [pretty: true,
charlists: :as_lists,
limit: :infinity,
printable_limit: :infinity])
end
end
こんな感じで使用します。
iex> Deb.put 1..1000 |> Enum.chunk_every(10)
リストの見えない部分にバグある⇒こまる
以下のようなリストをIO.inspect
で出力した場合
iex(1)> IO.inspect 1..1000 |> Enum.chunk_every(10)
次のような表示になってしまい、全部出力できません。
このような表示の後ろにバグの原因があった場合、困ってしまいますよね?
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
[21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
[31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
')*+,-./012',
'3456789:;<',
'=>?@ABCDEF',
'GHIJKLMNOP',
'QRSTUVWXYZ',
'[\\]^_`abcd',
'efghijklmn',
'opqrstuvwx',
#
# 中略
#
[391, 392, 393, 394, 395, 396, 397, 398, 399, 400],
[401, 402, 403, 404, 405, 406, 407, 408, 409, ...],
[411, 412, 413, 414, 415, 416, 417, 418, ...],
[421, 422, 423, 424, 425, 426, 427, ...],
[431, 432, 433, 434, 435, 436, ...],
[441, 442, 443, 444, 445, ...],
[451, 452, 453, 454, ...],
[461, 462, 463, ...],
[471, 472, ...],
[481, ...],
[...],
...
]
IO.inspectとinspect
通常であれば、IO.ipspectのオプションの指定でなんとかなりそうなものなのですが、limit:
を指定しても表示は変わってくれません。
詳しくは@melpon さんの「inspect について調べてみた」の記事にもある通り、inspect関数を使用する必要があります。
IO.inspecとinspect、似た者同士なのですが、少し違うから厄介なのです。
頻繁に使うはずなのに、正当ルートで調べても徒労に終わる残念なケースです。ここに書いた結論もスマートなものではないのですが、知っているに越したことはありません。
効率よく行きましょう!