5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ElixirAdvent Calendar 2024

Day 5

Elixirチートシートを作ろう、番外編その5 hexdoc見てたら、おや?デバッグ方法、こんなにあるの?

Last updated at Posted at 2024-12-24

1. OverView

どもども、うん、アドベントカレンダーの完走賞狙いなんだ、すまない。

hexdoc見てたら、おや?デバッグ方法、こんなにあるの?と言うお話をしてみたいと思います。

IO.inspect/2
dbg/2
Pry
Breakpoints
Observer
Other tools and community

ざっと見たのですが、現時点でIO.inspect/2、Pry、Breakpointsくらいはすぐにでも抑えねば!

随時、Elixir入門を参考にさせていただいております。
https://dev.to/gumi/elixir-21--21a1

2. IO.inspect/2

2.1 hexdocで確認

hexdocでIO.inspect/2を読むところからやりましょう。

@spec inspect(item, keyword()) :: item when item: var
Inspects and writes the given item to the device.

引数で与えられたItemをDeviceに書き出してくれると書いてありますね。
こっからが面白い。(俺だけか?)

It's important to note that it returns the given item unchanged.
This makes it possible to "spy" on values by inserting an IO.inspect/2 call
almost anywhere in your code, for example, in the middle of a pipeline.

翻訳すると…
重要なのは、指定された項目を変更せずに返すことです。
これにより、例えばパイプラインの途中など、コードのほぼどこにでもIO.inspect/2呼び出しを挿入して
値を「スパイ」することが可能になります。

…"It's important"とか書かれると、期待が広がりますねぇ。

2.2 IO.inspect/2を使ってみよう。

まずは、hexdocのサンプルから行ってみますか。
重要なオプション、label:width:が出てきております。

iex(2)> IO.inspect(<<0, 1, 2>>, width: 40)
<<0, 1, 2>>
iex(3)> IO.inspect(<<0, 1, 2>>, width: 4)
<<0,
  1,
  2>>

width: 4にしたのは、飽くまでもサンプルとしてですが、綺麗に改行してくれるものですね。
次、オプションlabel:

iex(5)> IO.inspect(1..100, label: "a wonderful range")
a wonderful range: 1..100
1..100

ラベルを付けてくれるので、とても便利ですね。

さて、パイプの中での使い方例を見てみましょう。

[1, 2, 3] |> IO.inspect(label: "before")
|> Enum.map(&(&1 * 2))
|> IO.inspect(label: "after")
|> Enum.sum()
before: [1, 2, 3]
after: [2, 4, 6]
12

…ちゃんと、前後がわかりやすく綺麗に出てますね。

では、もう一つbinding/0と組み合わせてみましょう。
binding/0は指定されたコンテキストのバインディングをキーワードリストとして返す変数ですが、
指定されたコンテキストがnilの場合、現在のコンテキストのバインディングが返されます。

ぶっちゃけ、そのスコープの変数のbinding状況を、全部出してくれます。

iex(30)> defmodule Example do
...(30)>   def show_binding do
...(30)>     x = 1
...(30)>     y = 2
...(30)>     IO.inspect(binding(),label: "Show binding:")
...(30)>   end
...(30)> end
iex(31)> Example.show_binding()
Show binding:: [x: 1, y: 2]
[x: 1, y: 2]

いちいち書かなくても、変数の状況が丸わかりですね。
これば便利、ではこの辺で…いや、もう一つちゃんとやりますから。

2.2 IO.inspect/3を使ってみよう。

h IO.inspect/3

                        def inspect(device, item, opts)

inspect/2のdeviceつきですね。第一引数にdeviceが加わってます。
これ、便利なんでメモしときます。

deviceをファイルに割り当てれば、記録が取れます。

{:ok, file} = File.open("example.txt", [:write])
IO.inspect(file, binding(),label: "Show binding:")
File.close(file)

実行結果はこんな感じになります

iex(20)> test=1
1
iex(21)> test2=2
2

type example.txt
Show binding:: [file: #PID<0.110.0>, test: 1, test2: 2]

と、言うわけでIO.inspect/2で遊んでみました。
…うん、ググればわかるって、まぁ、そう言わずに。

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?