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 6

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

Last updated at Posted at 2024-12-24

1. OverView

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

さて、hexdocにあるデバッグ方法を順を追って調べようと言う話題です。

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

順を追ってPryを…と思ったけど、これ、コードの変更が必要ですし。
すごい良い解説がネットにあふれてるので、お前書く必要ある?と言われると自信がない。
なので、次、Breakpointsに行きたいと思います。

え?Observer...起動したけど、理解が追いつかんかったw

2. break!

2.1 hexdocで確認

さて、ブレークポイントが設定出来るくらいで、特に面白くも無かろうと思ってたんですが、
h()を見てたら、意外と機能が豊富なので改心しました。

  • break!/2        - sets a breakpoint at Module.function/arity
  • breaks/0        - prints all breakpoints to the terminal
  • c/0             - a shortcut for continue/0
  • continue/0      - continues execution of the current process
  • n/0             - a shortcut for next/0
  • next/0          - goes to the next line of the current breakpoint
  • remove_breaks/0 - removes all breakpoints and instrumentation from all
    modules
  • whereami/1      - prints the current location and stacktrace in a pry
    session

作業の流れは、

  1. ブレークポイントを決めて、break!/2 でブレークポイントを設定します。

break! Example.double_sum/2で関数に入るところで止まる様にしております。

(base) C:\Users\nanbu\example>iex.bat -S mix
Erlang/OTP 27 [erts-15.2] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]

Interactive Elixir (1.18.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> break! Example.double_sum/2
1

そして、モジュールの実行です。

iex(2)>  Example.double_sum( 2, 4 )
Break reached: Example.double_sum/2 (lib/example.ex:3)

    1: defmodule Example do
    2:   def double_sum(x, y) do
    3:     hard_work(x, y)
    4:   end
    5:
    6:   defp hard_work(x, y) do

iex(3)>

プログラムが実行され、double_sumで止まっている事がわかりました。
さて、いろんなコマンドを使ってみましょう。

  1. whereami
    自分の位置やスタックとレースを表示してくれます。
iex(3)> whereami
Location: lib/example.ex:3

    1: defmodule Example do
    2:   def double_sum(x, y) do
    3:     hard_work(x, y)
    4:   end
    5:

    (example 0.1.0) Example.double_sum/2
    (elixir 1.18.0) lib/module/parallel_checker.ex:120: Module.ParallelChecker.verify/1

  1. Breakpointの操作

プログラムの実行の前に、remove_breaksとbreaksを紹介しましょう。

breaksはbreak pointの一覧を表示します。
remove_breaksはbreak pointを削除します。

以下、 break!でExample.double_sum/2でbreak pointを三回分設定、
breksで確認後、remove_breaksでbreak pointを削除しています。

iex(19)> break!(Example.double_sum/2, 3)
1
iex(20)> breaks

 ID   Module.function/arity   Pending stops
---- ----------------------- ---------------
 1    Example.double_sum/2    3

iex(21)> remove_breaks
:ok
iex(22)> breaks
No breakpoints set
iex(23)>
  1. プログラムの実行を継続

nextとcontinueがあります。
nextは一行だけ実行、次の行に移動します。continueは、そのまま処理を続けます。

next: 次の行を実行し、次のブレークポイントまたは次の行で停止します。
continue: プログラムの実行を再開し、次のブレークポイントで停止します。
nextはn, continueはcとリンクが定義されてます。
次の関数に入る、step-inがないみたいですねぇ、まぁ、以下の様にブレークポイントを設定すりゃいいだけだけど

iex(9)> breaks

 ID   Module.function/arity   Pending stops
---- ----------------------- ---------------
 1    Example.double_sum/2    2
 2    Example.hard_work/2     1

iex(10)> Example.double_sum( 2, 4 )
Break reached: Example.double_sum/2 (lib/example.ex:3)

    1: defmodule Example do
    2:   def double_sum(x, y) do
    3:     hard_work(x, y)
    4:   end
    5:
    6:   defp hard_work(x, y) do

iex(11)> next
Break reached: Example.hard_work/2 (lib/example.ex:7)

    4:   end
    5:
    6:   defp hard_work(x, y) do
    7:     x = 2 * x
    8:     y = 2 * y
    9:
   10:     x + y

nextを実行していくと、どんどん行が進むのがおわかりでしょうか?

iex(11)> next
Break reached: Example.hard_work/2 (lib/example.ex:7)

    4:   end
    5:
    6:   defp hard_work(x, y) do
    7:     x = 2 * x
    8:     y = 2 * y
    9:
   10:     x + y

iex(12)> next
Break reached: Example.hard_work/2 (lib/example.ex:8)

    5:
    6:   defp hard_work(x, y) do
    7:     x = 2 * x
    8:     y = 2 * y
    9:
   10:     x + y
   11:   end

iex(13)> next
Break reached: Example.hard_work/2 (lib/example.ex:10)

    7:     x = 2 * x
    8:     y = 2 * y
    9:
   10:     x + y
   11:   end
   12: end

こんな感じで、ゆっくりとデバッグが出来ます。

  1. 変数を調べるのは、はい、binding()で

昨日の今日なので、ハイ、binding()ですね。
以下の様に、ローカル変数xとyが表示されるのがわかるでしょうか?

iex(14)> binding()
[x: 4, y: 8]
iex(15)>

以上です。
意外と便利ですね。

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?