【RubyKaigi2023】debug.gem 1.8.0 で Ruby のデバッグをしてみる【VSCode】

# はじめに

Qiita株式会社でエンジニアをしている @wataru86 です。
Qiita株式会社は RubyKaigi 2023 に Platinum Sponsor として協賛・ブース出展しています！

https://zine.qiita.com/event/qiita-rubykaigi-2023-introduction/

僕もそのメンバーとして、現地で参加していました。本記事では、2日目の `@ono-max` さんによるセッション「Introduction of new features for VS Code debugging」で発表された debug.gem v1.8 の機能の概要と、実際に使う方法について簡単に説明します。

https://rubykaigi.org/2023/presentations/ono-max.html#day2

また、発表時のスライドは以下に公開されていました。

https://speakerdeck.com/onomax/introduction-of-new-features-for-vs-code-debugging

# debug.gem

debug.gem は Ruby3.1 からデフォルトでRubyに同梱されている gem です。ソースコードは以下リポジトリにあります。

https://github.com/ruby/debug

debug.gem 自体は以前から存在していますが、 先日公開された 1.8.0 で VSCodeによる Ruby のデバッグがさらに便利になっていました。特に、以下の2つの機能の概要と使い方を紹介します！

- Trace Inspector
- Debug Visualizer

## Trace Inspector

Trace Inspector は以下のように、「どの行でどのメソッドが呼ばれて〜」という情報が表示される機能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325392/cb157e62-22c6-6a93-bcef-9a2b99e0e83e.png)

実際に VSCode で試す方法を紹介します。実行環境は以下です。

```
λ ruby -v
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-darwin21]
λ rdbg -v
rdbg 1.8.0
```

VSCodeの拡張機能「VSCode rdbg Ruby Debugger」のインストールが必要です。

https://marketplace.visualstudio.com/items?itemName=KoichiSasada.vscode-rdbg

適当なディレクトリに `.vacode/launch.json` を作成し、VSCodeによるデバッグができるようにします。

```.vacode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "rdbg",
      "name": "Debug current file with rdbg",
      "request": "launch",
      "script": "${file}",
      "args": [],
      "askParameters": true,
      "useTerminal": true
    }
  ]
}
```

デバッグを行うファイルを作成します。

```sample1.rb
def foo(a, b)
  var1 = "var1"
  var2 = "var2"
  p a, b
end

def bar(c, d)
  foo c * 2, d * 3
end

puts "set breakpoint"
bar 10, 20
puts "set breakpoint"
```

これで準備が整いました！あとはブレークポイントを設定して、実行するだけです。
`puts "set breakpoint"` のところにブレークポイントを設定します。行番号の左をクリックすると、赤い点が表示さます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325392/ff2d94f8-001c-5b45-b580-6b7d4d722957.png)

ブレークポイントの設定ができたら、緑色の ▶︎ ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325392/173daf7e-70ea-a820-3fb2-90ad77877ea7.png)

以下のような表示が出てきたら、 Enter キーを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325392/cbc9b92d-a556-b4a4-6a2a-5f2d554d99cb.png)

問題がなければプログラムが実行され、1つ目のブレークポイントで止まります。
左下の `TRACE INSPECTOR` に `Enable Trace` と書かれているとことがあるので、それをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325392/09a42364-32d7-eb46-de24-95197c73fa6d.png)

これで Trace Inspector が有効になるので、「続行」ボタンを押して次のブレークポイントまで実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325392/cdfe5fb8-10cb-2fc3-dbe6-1c86b1202b36.png)

すると、以下のように `TRACE INSPECTOR` にトレースが表示されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325392/ecdd6728-a686-bff4-b033-84f9f5e148d2.png)

12行目で `bar` が呼ばれ、 7行目の `bar` の定義に進み、さらに 8行目で `foo`が呼ばれ...という流れが確認できました。

Trace Inspector にはもう一つ便利な機能があります。 `TRACE INSPECTOR` の「...」から　`Record And Replay` をオンにすると、その機能が使えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325392/1a12fff5-a723-5f81-4b76-44c7653e1ff9.png)

先ほどと同様に、2つ目のブレークポイントまですすめると、以下のように表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325392/f7626596-6ef5-6322-32c5-a46c1eae8394.png)

この機能は、各ステップの状態を保存して、そのステップでどの変数がどんな値だったか、メソッドがどの引数で呼ばれているかなどそれぞれ確認ができます！

## Debug Visualizer

VSCode　には Debug Visualizer という、デバッグ中の値を可視化する機能があります。
debug.gem 及び debugvisualizer.gem にっよって Ruby でもこの機能が使えるようになります。

例として、 デバッグ中の変数に ActiveRecord が入っている場合、それを表として表示できます！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325392/d47c9f03-e3c8-8231-8971-43d63cb3b7d1.png)

実際に VSCode 上で使えるようにする手順を紹介します。
今回、ActiveRecord の値を表示するために、`sqlite` で `sample.sqlite3` ファイルにデータベースを作成しておく必要があります。`sqlite3` コマンド等で以下SQLを投げるなどして、事前にデータを用意しました。

```sql
CREATE TABLE users(id text primary key, name text, age integer);
INSERT INTO users VALUES(1, "wataru86", 26);
INSERT INTO users VALUES(2, "ohakutsu", 25);
```

データの準備ができたら、実際にデバッグしていきます。以下の Ruby ファイルの `foo` の各状態の中身をデバッグしていきます。


```sample2.rb
require "bundler/inline"

gemfile do
  source "https://rubygems.org"
  gem "debugvisualizer"
  gem "nokogiri"
  gem "sqlite3"
  gem "activerecord"
end

require 'nokogiri'
require 'open-uri'
require 'json'
require 'active_record'

# Array
foo = [1, 70, 10, 3, 40, 30]

# Hash
foo = {"Sun": 50, "Mon": 120, "Tue": 80, "Wed": 150, "Thu": 180, "Fri": 220, "Sat": 100}

# Nokogiri
foo = Nokogiri::HTML(URI.open("https://example.com/"))

# ActiveRecord
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: "sample.sqlite3")
class User < ActiveRecord::Base ; end
foo = User.all

foo = 1
```

こちらも VSCode に拡張機能が必要なので、以下をインストールします。

https://marketplace.visualstudio.com/items?itemName=hediet.debug-visualizer

インストールができたら、コマンドパレットから `Debug Visualizer New View` を探して実行します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325392/90ab85c8-abf2-200c-614b-85789c73acc2.png)

すると左側に以下のようなタブが開かれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325392/dcbf8d38-331b-0a01-76f2-e9d56cce84f1.png)

これで準備は完了です。`foo` に各値を代入している箇所にブレークポイントを用意します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325392/fff2267b-3169-0915-42d2-b56cbb1f18fa.png)

緑色の 「▶︎」ボタンで実行します。
Visualizer に `foo` を入力すると、 `foo` の値が表示されますが、まだ Array に代入する前なので、　 nil です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325392/f3fdd180-9697-485f-5ae2-5baf7deaa6e9.png)

続行を押し、`foo` の値をもう一度表示すると、以下のように表示されます。x軸が index で、 y軸が要素の値です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325392/a0fd1864-6b68-f5ab-781c-29087247fb19.png)

`Extractor` `Visualizer` を変更することで、表示方法を変えることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325392/32660525-d98e-cfa2-3122-03b22a91e500.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325392/4ed7cb41-2deb-c636-2d9d-c80167947838.png)

デバッグを続行し、Array 以外も見てみましょう。

### Hash

棒グラフや円グラフとして表示できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325392/f5572cce-881e-221e-9aac-7c416e3f6c48.png)

### Nokogiri

木構造が表示され、閉じたり開いたりできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325392/2ece2b00-508c-361d-f29b-c79175816b9a.png)

### ActiveRecord

表が表示されます。 `age` で sort もできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325392/6add3bff-c27a-bb9a-8693-ea0bbe684add.png)

# さいごに 

debug.gem に便利な機能が増えていてとても驚きました！Rubyの VSCode でのデバッグ技術はここ最近で非常に進化していますね。これからもっと便利になると嬉しいです！

昨日も RubyKaigi 2023 1日目のセッションに関する記事を投稿しています！

https://qiita.com/wataru86/items/574e290c2fafc7a3e0e6

また、1日目の参加レポートも Qiita Zine に投稿しています。是非ご覧ください。

https://zine.qiita.com/event/qiita-rubykaigi-2023-day1-report/?utm_source=qiita&utm_content=official_column&utm_medium=referral

明日も体力が残っていれば記事を投稿したいです！！ 

# 参考文献

- [Ruby 3.1 の debug.gem を自慢したい - クックパッド開発者ブログ](https://techlife.cookpad.com/entry/2021/12/27/202133)