web-dev-qa-db-ja.com

Rubyスクリプトをデバッグするにはどうすればよいですか?

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

しかし、それは機能しません!

助けてください。自分でプログラムをデバッグするにはどうすればよいですか?

147
Andrew Grimm

PryGitHub )を使用します。

経由でインストール:

$ gem install pry
$ pry

それから加えて:

require 'pry'; binding.pry

あなたのプログラムに。

ただし、pry 0.12.2の時点では、nextbreakなどのナビゲーションコマンドはありません。他のいくつかのgemには、これが追加されています。たとえば、 pry-byedebug を参照してください。

133
horseyguy
  1. Rubyの場合:

    Ruby -rdebug myscript.rb 
    

    その後、

    • b <line>:ブレークポイントを置く
    • およびn(ext)またはs(tep)およびc(ontinue)
    • 表示用のp(uts)

    (Perlデバッグなど)

  2. Railsの場合:サーバーを起動します

    script/server --debugger
    

    コードにdebuggerを追加します。

110
germanlinux

手すりが推奨するように:てこを使用してください!私はこれにのみ同意できます。

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

追加する必要があります

require 'pry'

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

binding.pry

物事を見たい場所で(これは古典的なIDE環境でブレークポイントをトリガーするようなものです)

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

binding.pry

行の場合、プログラムのすべてのコンテキストを手元に置いて、pry replに直接アクセスできるため、周囲のすべてを探索したり、すべてのオブジェクトを調査したり、状態を変更したり、その場でコードを変更したりすることができます。

現在のメソッドのコードを変更することはできないと思うので、悲しいことに、実行する次の行を変更することはできません。しかし、良いRubyコードはとにかく単一行になる傾向があります;-)

55
edx

例外の発生によるデバッグは、print]ログステートメントを細かく調べるよりも--- [はるかに簡単であり、ほとんどのバグでは、一般的にはるかに速い = prybyebugのようなirbデバッガーを開くよりも。これらのツールは最初のステップではありません。


Ruby/Railsの迅速なデバッグ:

1.高速メソッド:Exceptionを発生させ、その結果を.inspect発生させます

fastestデバッグする方法Ruby(特にRails)コードは、メソッドまたはオブジェクト(例:raise)で.inspectを呼び出している間に、コードの実行パスに沿ってfoo例外になります:

raise foo.inspect

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

この手法は、quicklyオブジェクトまたはメソッドの検査(eg nil)や、特定の行内でコード行がまったく実行されているかどうかをすぐに確認する場合に便利です。コンテキスト。

2.フォールバック:Rubyを使用します IRB byebugまたはpryのようなデバッガー

コード実行フローの状態に関する情報を取得した後にのみ、prybyebugなどのRubygem irbデバッガーに移行することを検討してください。


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

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

それはあなたが行動する前にエラーメッセージを読むことを意味します慎重に完全にそれがあなたに伝えようとしていることを理解します。質問、この順序で、エラーメッセージを読むとき:

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

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


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

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

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

@foo = Foo.new

...

@foo.bar

次のようなエラーが表示されます:

undefined method "bar" for Nil:nilClass

初心者はこのエラーを見て、問題はメソッドbarndefinedであると考えています。 それは違います。このエラーでは、重要な実際の部分は次のとおりです。

for Nil:nilClass

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

残念ながら、このエラーの記述方法(undefined method "bar" for Nil:nilClass)により、このエラーはbarundefinedであることに関係していると簡単にintoされてしまいます。注意深く読んでいないと、このエラーにより、初心者がbarFooメソッドの詳細を誤って掘り下げ、オブジェクトが間違ったクラス(この場合はnil)であることを示唆するエラーの一部が完全に欠落します。これは間違いであり、エラーメッセージ全体を読むことで簡単に回避できます。

概要:

デバッグを開始する前に、常に慎重にentireエラーメッセージを読むを読んでください。つまり、常にエラーメッセージ内のオブジェクトのタイプclassをチェックしますfirst、次にそのmethodsbeforeエラーが発生していると思われるスタックトレースまたはコード行の調査を開始します。これらの5秒は、5時間のフラストレーションを軽減します。

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

28
Kelsey Hannan
  1. 可能な限り変数を出力します。 (これはprintfデバッグと呼ばれます)これを実行するには

    STDERR.puts x.inspect
    

    または

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

    これを入力しやすくしたい場合は、 exemplor gemを使用できます。

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

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

  3. バイナリチョップの概念を理解する(以下の引用は Practices of an Agile Developer

    問題空間を半分に分け、どちらに問題が含まれているかを確認します。次に、その半分を再び半分に分割し、繰り返します。

  4. バイナリチョップで成功した場合、期待どおりの動作をしない単一の行があることに気付くかもしれません。例えば

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

    falseを返すと思われる場合でも、trueの値を指定します。その場合は、ドキュメントをご覧ください。ドキュメントのWebサイトには、 Ruby-doc.org または APIdock が含まれます。後者の場合、右上隅の虫眼鏡の横にinclude?と入力し、その下にArrayがあるinclude?を選択します(クラス[1, 2, 3]がわからない場合は、irbに[1, 2, 3].classと入力します)。 to include?(Array) で、その機能を説明しています。

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

19
Andrew Grimm

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

2017年へようこそ^ _ ^

さて、新しいIDEを試すことに反対していなければ、freeで次のことができます。

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

  1. Vscodeをインストールする
  2. Ruby Dev Kitをまだインストールしていない場合はインストールします
  3. Vscode用のRuby、Ruby-linter、Ruby-rubocop拡張機能をインストールする
  4. 任意のgemを手動でインストールします rubyide/vscode-Ruby指定 (必要な場合)
  5. launch.jsonマクロを使用して"cwd"およびand"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の内部用です。もう一方を選択する場合は、 here に移動できます。 vscodeの拡張機能部分に移動します。あなたはこれをいくつかの方法で行うことができますが、最も将来性のある方法はおそらくヒットするでしょう F1、入力 ext Extensions:Install Extensionsというオプションが使用可能になるまで。代替手段は CtrlShiftx そしてトップメニューバーから、View->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年半ばと暗いテーマでこれに似たメニューでデバッグできるはずです: enter image description here コールスタック、変数ビューアーなどの楽しいものすべて.

最大のPITAは、1)pre-reqをインストールすること、2).vscode\launch.jsonファイルを構成することを忘れないことです。将来のプロジェクトに荷物を追加する必要があるのは#2だけで、上記のような一般的な設定をコピーするだけです。おそらくもっと一般的な設定の場所がありますが、私は頭の外を知りません。

7

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

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

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

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

6
NIA

このgemを発見しました(PryをMRI Ruby 2.0+のデバッガに変えます)

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

でインストール:

gem install pry-byebug

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

require 'pry'; binding.pry

ただし、Vanilla pryとは異なり、このgemには、nextstepbreakなどのGDBに似た主要なナビゲーションコマンドがあります。

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.
6
nurettin
  1. 途中で変数を印刷できます
  2. -w(警告)フラグをオンにする
  3. Ruby-debug などのツールを使用します
5
ghostdog74

Ruby 2.4.0の時点では、REPLプログラムの途中でIRB Rubyセッションを開始する方が簡単です。デバッグするプログラム内のポイントに次の行を配置します。

require 'irb'
binding.irb

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

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

5
David Grayson

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

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

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

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

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

5
DavidSilveira

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

#!/usr/bin/env Ruby

に:

#!/usr/bin/env Ruby -rdebug

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

  • Continueのc(次の例外、ブレークポイント、またはdebuggerの行まで)、
  • 次の行のn
  • w/whereは、フレーム/呼び出しスタックを表示します。
  • lは現在のコードを表示し、
  • キャッチポイントを表示するcat
  • hを参照してください。

Ruby-debugを使用したデバッグRuby-debug gemのキーショートカット も参照してください。


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

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

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

より適切に機能する場合は、lldbgdbに置き換えます。所有していないプロセスをデバッグするには、Sudoをプレフィックスとして付けます。

5
kenorb

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

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

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

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

enter image description here

2.デバッグを開始する

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

enter image description here

enter image description here

3.変数などを検査します。

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

enter image description here

参考のための詳細情報

  1. RubyMineを使用してリモートデバッグを実行する を使用する場合は、実行できます。
  2. RubyMineを使用してRailsをリモートデバッグしてdocker内で実行します の場合も簡単です。
3
Yuci

さて、Ruby標準ライブラリには使いやすいgdbのようなコンソールデバッガーがあります: http://Ruby-doc.org/stdlib-2.1.0/libdoc/debug/rdoc/DEBUGGER__。 html 追加のgemをインストールする必要はありません。 Railsスクリプトもそのようにデバッグできます。

例えば.

def say(Word)
  require 'debug'
  puts Word
end
2
Forvater

printfデバッグ

デバッグ技術については常に論争があり、一部の人はprint文によるデバッグを好む人もいれば、デバッガで掘り下げることを好む人もいます。

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

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

しかし、ある仕事を始めたばかりで、大量のコードを理解する必要がある場合は、そこに足を踏み入れ、いくつかのブレークポイントをあちこちに置いて、それがどのように機能するかを理解することが本当に便利です。

コードがどのように織られているかを理解する必要があります。

あなたが他の人々のソフトウェアに慣れていない場合、それはあなたがそこをステップスルーするのに役立つかもしれません。

彼らが巧妙な方法でそれを整理したかどうか、またはそれがたわごとの束であるかどうかすぐにわかります。

2
edx

さまざまな機能を持つ多くのデバッガがあり、それらに基づいて選択を行います。私の優先順位は pry-moves で満足しました:

  • 使用方法に関するわかりやすい情報
  • 直感的なステップ(ブロックに簡単に足を踏み入れるなど)
  • 「ステップバック」(必要に応じて部分的に移動する)
1

すべてのデバッガの母は、普通の古い印刷画面です。ほとんどの場合、おそらくいくつかの単純なオブジェクトのみを検査する必要があります。すばやく簡単な方法は次のとおりです。

@result = fetch_result

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

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

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

これは私のユースケースの90%で機能すると思います。 Ruby-debugを使用することもできますが、ほとんどの場合それはやり過ぎです。

1
Aaron Qian