Rubyスクリプトをデバッグする方法[終了]


153

次のRubyコードをインターネットからコピーしていくつかの変更を加えましたが、機能しません。

プログラムを自分でデバッグするにはどうすればよいですか?


1
投票を再開します。OPは明らかにGDBのようなステップデバッグを望んでいます。
Ciro Santilli郝海东冠状病六四事件法轮功

回答:


145

PryGitHub)を使用します。

インストール:

$ gem install pry
$ pry

それから加えて:

require 'pry'; binding.pry

あなたのプログラムに。

以下のようpry0.12.2しかし、など全くナビゲーションコマンドが存在しないnextbreakなど、いくつかの他の宝石は、さらに、例えば参照、これを提供しますpry-byedebug


10
また、Pry(間違いなくライフチェンジャー!)を使用することをお勧めします。プログラムにインストールして必要になると、ブレークポイントの設定は書き込みと同じくらい簡単binding.pryです。また..動的編集にカラー完了、ドキュメントの検索、および可能性が付属していますし、方法をリロード
アンドレア・フィオーレ

5
Pryのホームページは、pryrepl.orgから入手できます。
shadowbq 2013年

4
Pry/ byebugは素晴らしいですが、デバッグ時の最初のステップではありません。ほとんどの場合、例外を発生raise object.inspectさせると、IRBセッションを開くよりも早く問題が解決されます。例外を発生させるなどの簡単な解決策では問題を解決できない場合は、コンソールデバッガーのみを使用することをお勧めします。
ケルシーハンナン

3
でシングルステップコードにする方法はありpryますか?私はそれを行う方法を見つけることができませんでした。そしてそれは私がデバッガーに期待することです。
jpetazzo

2
@jpetazzoはい、「next」と入力します
marcbest

114
  1. Rubyの場合:

    ruby -rdebug myscript.rb 

    その後、

    • b <line>:ブレークポイントを置く
    • and n(ext)またはs(tep)andc(ontinue)
    • p(uts) ディスプレイ用

    (perl debugと同様)

  2. Rails:サーバーを起動

    script/server --debugger

    debuggerコードを追加します。


7
-rdebugはゴミです。そして維持されていない。Pryを使用します(他の回答を参照)。
Snowcrash 2013年

3
@SnowCrash-なぜそれ-r debugがゴミだと言うのですか?
sid smith 14

8
-rdebugで:デバッグするための変更のソースファイルへの必要はありません
germanlinux

2
新しいRuby / Railsアプリケーションでは、Pryが正解です。しかし、私は1時間以上かけてfacets、gem要件にある特定のバージョンのRails 2.2アプリで実行するPryの古いバージョンを見つけようとしましたが、失敗しました。古代のRailsアプリでruby-debugは少し厄介ですが、仕事は完了です。
Abe Voelker 14

56

手すりがお勧めです:こじ開けてください!私はこれに同意することしかできません。

pryはirbよりはるかに優れたreplです。

追加する必要があります

require 'pry'

ソースファイルに追加して、ソースコードにブレークポイントを挿入します

binding.pry

物事を確認したい場所(これは、クラシックIDE環境でブレークポイントをトリガーするようなものです)

プログラムがヒットしたら

binding.pry

行を開くと、プログラムのすべてのコンテキストが手元にあるため、pry replに直接投入されるので、すべてを探索し、すべてのオブジェクトを調査し、状態を変更し、その場でコードを変更することさえできます。

あなたが現在いるメソッドのコードを変更することはできないので、実行する次の行を変更できないのは残念です。しかし、良いルビコードはとにかく単一行になる傾向があります;-)


30

例外を発生させることによるデバッグは、ログステートメントを細かく調べるよりはるかに簡単ですprint。また、ほとんどのバグでは、通常、またはのようなirbデバッガーを開くよりはるかに高速です。これらのツールは、常に最初のステップではありません。prybyebug


Ruby / Railsをすばやくデバッグする:

1.高速メソッド:Exceptionthenと.inspectその結果を発生させる

最速(特にRailsの)コードをRubyのをデバッグする方法があるにraise呼び出し中にあなたのコードの実行パスに沿って例外.inspectメソッドまたはオブジェクト(例えば上foo):

raise foo.inspect

上記のコードでは、をraiseトリガーしExceptionコードの実行停止し、デバッグしようとしている行.inspectのオブジェクト/メソッド(つまりfoo)に関する情報を含むエラーメッセージを返します。

この手法は、オブジェクトやメソッドをすばやく調べたり(たとえばnil)したり、特定のコンテキスト内でコード行がまったく実行されていないかどうかを即座に確認したりするのに役立ちます。

2.フォールバック:使用ルビーIRBのようなデバッガbyebugpry

コード実行フローの状態に関する情報を取得した後でのみ、Ruby gem irbデバッガーなどに移動することを検討するprybyebug、実行パス内のオブジェクトの状態をより深く掘り下げることができます。


一般的な初心者向けアドバイス

問題をデバッグしようとするときは、常に次のことをお勧めします。 !@#$ ingエラーメッセージ(RTFM)を読む

エラーメッセージを読んだことを意味し、慎重かつ完全にあなたがなるように処理する前に、あなたを教えしようとしているものを理解しています。 デバッグするときは、エラーメッセージを読むときに、次の精神的な質問をこの順序で行ってください。

  1. エラーはどのクラスを参照していますか?(つまり、正しいオブジェクトクラスを持っているか、それとも私のオブジェクトnilですか?
  2. エラーはどのような方法で参照していますか?(つまり、それらはメソッド内の型です。このメソッドをオブジェクトのこの型/クラスで呼び出すことができますか?
  3. 最後に、最後の2つの質問から推測できるものを使用して、どのコード行を調査する必要がありますか?(注意:スタックトレースのコードの最後の行は、必ずしも問題のある場所ではありません。)

スタックトレースでは、プロジェクトからのコード行(たとえばapp/...、Railsを使用している場合はで始まる行)に特に注意してください。問題の99%はあなた自身のコードにあります。


この順序で解釈することが重要である理由を説明するには...

たとえば、多くの初心者を混乱させるRubyエラーメッセージ:

ある時点でそのように実行するコードを実行します。

@foo = Foo.new

...

@foo.bar

そしてあなたは次のようなエラーを受け取ります:

undefined method "bar" for Nil:nilClass

初心者はこのエラーを見て、問題はメソッドbar未定義であることだと思います。そうではありません。このエラーで重要な実際の部分は次のとおりです。

for Nil:nilClass

for Nil:nilClassつまり、それ@fooはニルです! インスタンス変数で@fooはありませんFoo!あなたはであるオブジェクトを持っていますNil。このエラーが表示さbarれた場合は、クラスのオブジェクトに対してメソッドが存在しないことをrubyが伝えようとしているだけですNil。(まあまあ!クラスでFooはなくオブジェクトのメソッドを使用しようとしているのでNil

残念ながら、このエラーの記述方法(undefined method "bar" for Nil:nilClass)により、このエラーが存在していることに関係しbarていると思われがちundefinedです。注意深く読まないと、このエラーにより、初心者は誤ってbar上のメソッドの詳細Fooを調べてしまい、オブジェクトが間違ったクラス(この場合はnil)であることを示唆するエラーの一部を完全に見逃してしまいます。エラーメッセージ全体を読むことで簡単に回避できるミスです。

概要:

デバッグを開始する前に常にエラーメッセージ全体を注意深く読んでください。ことは:常にチェックし、クラスのエラーメッセージにオブジェクトの種類を最初に、次に、その方法を前にあなたは、エラーが発生するかもしれないと思う場所を任意のスタックトレースやコードの行にsleuthing始めます。この5秒で、5時間のフラストレーションを節約できます。

tl; dr:印刷ログに目を細めないでください例外を発生させるか、代わりにirbデバッガーを使用してください。デバッグする前にエラーを注意深く読んでウサギの穴を避けてください。


3
印刷ログを読むのは面倒なことだと私は同意しますが、そもそもデバッガを使用しないことをお勧めするのは非常に悪いアドバイスです。ブレークポイントを追加してトリガーすることは、例外を発生させることとまったく同じですが、アプリケーションの現在の状態を完全に把握できます。疑わしい状態の検査の結果としてさらに質問が出てきた場合は、さらに別の例外を追加してアプリケーションを再起動する代わりに、対話的にドリルダウンできます。
Patrick R.

2
@PatrickR。私の経験では、IRBデバッガーは、コードのどこに問題があるのを正確に突き止めようとしているときの最初のステップとしては適切ではありません。多くのIRBブレークポイントを追加および削除するには、例外を追加するよりも時間がかかります。また、初心者が例外を使用して悪い仮定を取り除くことができるように、コードの制御フローについて明確な回答を与えないでください。IRBブレークポイントも忘れがちで、要求がハングしたときに混乱を招きます。問題がどこにあるかが正確にわかっていて、その状態をデバッグする必要がある場合は、必ずIRBデバッガーから始めてください。しかし、それはしばしば真実ではありません。
Kelsey Hannan

1
ハァッ!エラーメッセージを読むことはRubyに役立ちますが、他のスクリプト言語ですか?気にしないことでOPを責めることはできません。
kayleeFrye_onDeck 2017

1
私の最初の反応は@PatrickR。に似ていましたが、とにかくこれを試しました。結局、私はこれが悪いアドバイスであるか、または多分最もよく言えば、私が持っているものとは異なるユースケースに合わせたアドバイスだと思います。特に、(a)Railsを使用していない場合、および(b)エラーが発生してもエラーや例外は発生しない場合、つまりコードが数値を計算する場合、それは誤った数値です。それ以外の場合はクラッシュを実行するプログラムをどこに作成するかを繰り返し推測することは戦略ですが、再起動と再実行を続けなければならないので、それはより多くの作業です。各サイクルには、無駄な起動時間があります。
ブリック

20
  1. 可能な限り変数を出力します。(これはprintfデバッグと呼ばれます)これを行うには、次のコマンドを実行します。

    STDERR.puts x.inspect

    または

    STDERR.puts "Variable x is #{x.inspect}"

    これをより簡単に入力したい場合は、エグザンプラー gem を使用できます。

  2. 警告をオンにします。ruby実行している場合は、-wスイッチで実行します(例:)ruby -w script.rb。irbから実行していて、1.9.2より前のバージョンのrubyを使用している場合は$VERBOSE = true、セッションの開始時に入力します。インスタンス変数のスペルを間違えた場合、警告が出されると、

    警告:インスタンス変数@valeusが初期化されていません

  3. バイナリチョップの概念を理解する(次の引用はアジャイル開発者の実践からのものです

    問題の空間を半分に分割し、どの半分に問題が含まれているかを確認します。次に、その半分をもう一度半分に分けて繰り返します。

  4. バイナリチョップで成功した場合、期待どおりの動作を行わない1行が存在することがあります。例えば

    [1, 2, 3].include?([1,2])

    falseあなたがそれが返すだろうと思っていても、の値を与えますtrue。その場合は、ドキュメントをご覧ください。ドキュメントのWebサイトには、ruby-doc.orgまたはAPIdockが含まれます。後者の場合は、include?右上隅の近くにある虫眼鏡の横に入力し、その下にあるものinclude?を選択Arrayし(クラス[1, 2, 3]がわからない場合は、[1, 2, 3].classirbと入力します)、含めますか?(配列)、それが何をするかを説明します。

    ただし、ドキュメントが役に立たない場合、なぜスクリプト全体が何をしていないのかではなく、特定の行がどのようにして何をしていないのかについて質問できれば、良い答えが得られる可能性が高くなります。そうすべき。


7

すべてのものを削除します

2017年へようこそ^ _ ^

さて、あなたが新しいIDEを試すことに反対していなければ、無料で以下を行うことができます。

クイックインストラクション

  1. vscodeをインストールする
  2. Ruby Dev Kitをまだインストールしていない場合はインストールします
  3. vscodeのRuby、ruby-linter、およびruby-rubocop拡張機能をインストールする
  4. 必要に応じて、rubyide / vscode-rubyが指定するgemを手動でインストールします。
  5. マクロlaunch.jsonを使用"cwd"しておよび "program"フィールドを使用するようにを構成する{workspaceRoot}
  6. フィールドを追加"showDebuggerOutput"し、それを設定しますtrue
  7. デバッグ設定のすべての場所でブレークポイントを有効にする "debug.allowBreakpointsEverywhere": true

詳細な手順

  1. Visual Studio Code akaをダウンロードしてくださいvscode。これはVisual Studioと同じではありません。これは無料で軽量であり、一般的には高く評価されています。
  2. Ruby Dev Kitをインストールします。こちらのリポジトリの指示に従ってください:https : //github.com/oneclick/rubyinstaller/wiki/Development-Kit
  3. 次に、Webブラウザーを介して、またはIDE内に拡張機能をインストールできます。これはIDEの内部用です。他を選択した場合、ここに行くことができます。vscodeのExtensions部分に移動します。いくつかの方法でこれを実行できますが、最も将来性の高い方法は、おそらくF1を押し、Extensions:Install Extensionsext呼ばれるオプションが利用可能になるまで入力することです。代替は、トップメニューバーから、CtrlShiftxView->Extensions
  4. 次に、次の拡張機能が必要になります。これらは100%必要なわけではありませんが、いじくり回した後、何を保持するかを決定させていただきます。
    • ルビー; 拡張機能の作者Peng Lv
    • ruby-rubocop; 拡張作者みそぎ
    • ルビーリンター; 拡張機能の作者Cody Hoover
  5. rubyスクリプトのディレクトリ内に、コマンドラインを介して呼び出されるディレクトリを作成します。そこに、いくつかの構成オプションを格納する場所.vscodeと呼ばれるファイルを作成しlaunch.jsonます。
    • launch.json 内容物

{ "version": "0.2.0", "configurations": [ { "name": "Debug Local File", "type":"Ruby", "request": "launch", "cwd": "${workspaceRoot}", "program": "{workspaceRoot}/../script_name.rb", "args": [], "showDebuggerOutput": true } ] }

  1. 手動でのgemのインストールについては、拡張機能の作成者からの指示に従ってください。今のところここにあります:https : //github.com/rubyide/vscode-ruby#install-ruby-dependencies
  2. おそらく、好きな場所にブレークポイントを置くことができるでしょう。このオプションを有効にしないと、混乱が生じる可能性があります。これを行うには、上部のメニューバーに移動してFile->Preferences->Settings(またはCtrl,)を選択し、Debugセクションに到達するまでスクロールします。それを展開して、呼ばれる"debug.allowBreakpointsEverywhere"フィールドを探しますtrue。そのフィールドを選択し、鉛筆のような小さなアイコンをクリックして、に設定します。

すべての楽しいことを行った後、2017年半ばと暗いテーマの場合と同様のメニューでブレークポイントを設定してデバッグできるここに画像の説明を入力してくださいようになります。コールスタックや変数ビューアなどのすべての楽しいもので。

最大のPITAは、1)前提条件のインストール、および2).vscode\launch.jsonファイルの構成を忘れないことです。#2のみが将来のプロジェクトに手荷物を追加する必要があり、上記のような一般的な十分な構成をコピーするだけで済みます。おそらくもっと一般的なconfigの場所がありますが、頭の上からはわかりません。


今が2018年です '残念ながら、ここに記載したプラグインを使用して単体テストをデバッグすることはできません…😕かなり悲しいです。
MonsieurDart

1
@MonsieurDart私がこれを書いたとき、それはルビスクリプトの基本的なデバッグのためのものでした。単体テストについては特に何も知りません。この回答が正しくないか、古くなっている場合は、注意が必要な点と、その処理を高速化するのに役立つ情報をお知らせください。
kayleeFrye_onDeck 2018年

@kayleeFrye_onDeckさん、こんにちは!あなたの反応は素晴らしいです、私はあなたにそれを完全に与えます。しかし、前回Peng LvのVSC用Rubyプラグインを確認したところ、単体テスト(またはその他のテスト)内にブレークポイントを設定できませんでした。これは、プラグインの既知の制限の1つでした。VSCのインスタンスを設定する前に、このことを知っておく必要があると思います。これには時間がかかり、多くの人にとって、テストを実行することがコードの記述とデバッグの一番の方法です。😊–
MonsieurDart

6

現時点で適切なツールを選択してコードをデバッグするために、このビデオを強くお勧めします。

https://www.youtube.com/watch?v=GwgF8GcynV0

個人的には、このビデオで2つの大きなトピックを取り上げます。

  • Pryはデバッグデータに最適です。「Pryはデータエクスプローラーです(sic)」
  • デバッガは段階的にデバッグする方が良いようです。

それは私の2セントです。


6

他のすべての回答はすでにほとんどすべてを与えています...ほんの少しの追加。

さらにIDEに似たデバッガー(CLI以外)が必要で、Vimをエディターとして使用することを恐れない場合は、Vim Ruby Debuggerプラグインをお勧めします。

そのドキュメントはかなり簡単なので、リンクをたどって見てください。つまり、エディターの現在の行にブレークポイントを設定したり、一時停止時にniftyウィンドウでローカル変数を表示したり、ステップオーバー/インしたりすることができます。ほとんどすべての通常のデバッガー機能です。

Railsの豊富なロガー機能を使用する必要がほとんどなくなったものの、私にとっては、このvimデバッガーをRailsアプリのデバッグに使用することは非常に楽しかったです。


6

私はこの宝石を発見しました(PryをMRI Ruby 2.0+のデバッガーに変えます)

https://github.com/deivid-rodriguez/pry-byebug

インストール:

gem install pry-byebug

次に、とまったく同じようpryに使用して、改行する行をマークします。

require 'pry'; binding.pry

バニラてことは異なりただし、この宝石は、いくつかの重要GDBのようなナビゲーションは、次のようなコマンドをしているnextstepbreak

break SomeClass#run            # Break at the start of `SomeClass#run`.
break Foo#bar if baz?          # Break at `Foo#bar` only if `baz?`.
break app/models/user.rb:15    # Break at line 15 in user.rb.
break 14                       # Break at line 14 in the current file.

5
  1. 途中で変数を出力できます
  2. -w(警告)フラグをオンにする
  3. ruby-debugなどのツールを使用する

2
それirbは素晴らしい出発点です。疑わしい小さなチャンクでirbを使用してみてください。ruby-debug(Ruby 1.9+の場合はruby-debug19)が大好きです。実行中のプログラムを停止し、変数を調べ、irbにドロップして、実行を続けることが簡単にできるからです。
Tin Man

5

Rubyシェルスクリプトを簡単にデバッグするには、最初の行を次のように変更します。

#!/usr/bin/env ruby

に:

#!/usr/bin/env ruby -rdebug

その後、デバッガーコンソールが表示されるたびに、以下を選択できます。

  • c続行(次の例外、ブレークポイント、または次の行までdebugger):
  • n 次の行の場合、
  • w/ whereフレーム/コールスタックを表示します。
  • l 現在のコードを表示するには、
  • cat キャッチポイントを表示します。
  • h さらにヘルプが必要です。

参照してください:ルビー・デバッグでデバッグルビー・デバッグ宝石のキーのショートカット


スクリプトがハングしただけでバックトレースが必要な場合は、次のようにlldb/ を使用してみてくださいgdb

echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -nf ruby)

プロセスのフォアグラウンドを確認します。

うまく機能lldbするgdb場合はに置き換えます。sudo非所有プロセスをデバッグするための接頭辞。


1
ruby-debugはかなり時代遅れに見えます。ruby-debugのgitリポジトリには、今年のコミットが1つしかありません-まだ積極的にメンテナンスされていますか?
Andrew Grimm

また、ルビーがパッケージ化されているように見えるので、ピンチのときに最適です。正解です。
ブリードリー2017

5

Ruby 2.4.0以降、Rubyプログラムの途中でIRB REPLセッションを開始する方が簡単です。これらの行を、デバッグするプログラム内の位置に置きます。

require 'irb'
binding.irb

Rubyコードを実行してローカル変数を出力できます。Ctrl + Dを入力するかquit、REPLを終了してRubyプログラムを実行し続けます。

putsおよびpを使用して、プログラムの実行中にプログラムから値を出力することもできます。


4

RubyMineを使用している場合、rubyスクリプトのデバッグは単純で簡単です。

Rubyスクリプトhello_world.rbがあるとします。

1.ブレークポイントを設定する

以下のように6行目にブレークポイントを設定します。

ここに画像の説明を入力してください

2.デバッグを開始します

これで、デバッガーを起動してスクリプトを実行できます。

ここに画像の説明を入力してください

ここに画像の説明を入力してください

3.変数などを検査する

その後、実行がブレークポイントに到達すると、変数などを検査できるようになります。

ここに画像の説明を入力してください

あなたの参照のための詳細情報

  1. RubyMine使用してリモートデバッグを行う場合は、そうすることができます。
  2. RubyMine使用してdocker内で実行されているリモートデバッグレール使用する場合も簡単です。

RubyMineで外部ライブラリをデバッグする方法はありますか?
Am33d

2

printfデバッグ

デバッグ手法については常に論争があり、printステートメントでデバッグしたい人もいれば、デバッガーを深く掘り下げたい人もいます。

両方のアプローチを試すことをお勧めします。

実際、古いUnixの男性の1人は最近、printfデバッグがいくつかの点で彼のために行くためのより速い方法であると言いました。

しかし、仕事に慣れておらず、コードの大きな塊を理解する必要がある場合は、そこを一歩進み、あちこちにいくつかのブレークポイントを置き、それがどのように機能するかを理解することが非常に役立ちます。

これにより、コードがどのように織り込まれているかがある程度理解できるはずです。

他の人のソフトウェアを初めて使用する場合は、そこを一歩進むのに役立つ場合があります。

彼らがそれを巧妙な方法で配置したのか、それが単なるたわごとなのか、すぐにわかります。


これは間違いなく最良の答えです、それは場合によります
menriquez


1

すべてのデバッガーの母は、プレーンな古い印刷画面です。ほとんどの場合、いくつかの単純なオブジェクトのみを検査したいと思うでしょう。すばやく簡単な方法は次のとおりです。

@result = fetch_result

p "--------------------------"
p @result

これにより、@ resultの内容が簡単に識別できるように前に行を付けてSTDOUTに出力されます。

ボーナスは、Railsのようなオートロード/リロード対応のフレームワークを使用する場合、アプリを再起動する必要すらありません。(デバッグしているコードがフレームワーク固有の設定のためにリロードされない限り)

これは、私にとってユースケースの90%で機能することがわかりました。ruby-debugを使用することもできますが、ほとんどの場合、やりすぎです。


1

選択に基づいて、さまざまな機能を持つ多くのデバッガがあります。私の優先事項は、こじ開け動作に満足しました。

  • 使用方法に関する迅速に理解できる情報
  • 直感的なステップ(ブロックへの簡単なステップインなど)
  • 「後戻り」(部分的にこじ開けると、ニーズが部分的に満たされます)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.