次のRubyコードをインターネットからコピーし、いくつかの変更を加えました。
しかし、それは機能しません!
助けてください。自分でプログラムをデバッグするにはどうすればよいですか?
経由でインストール:
$ gem install pry
$ pry
それから加えて:
require 'pry'; binding.pry
あなたのプログラムに。
ただし、pry
0.12.2の時点では、next
、break
などのナビゲーションコマンドはありません。他のいくつかのgemには、これが追加されています。たとえば、 pry-byedebug
を参照してください。
Rubyの場合:
Ruby -rdebug myscript.rb
その後、
b <line>
:ブレークポイントを置くn(ext)
またはs(tep)
およびc(ontinue)
p(uts)
(Perlデバッグなど)
Railsの場合:サーバーを起動します
script/server --debugger
コードにdebugger
を追加します。
手すりが推奨するように:てこを使用してください!私はこれにのみ同意できます。
pryはirbよりもはるかに優れたreplです。
追加する必要があります
require 'pry'
ソースファイルに追加し、ソースコードにブレークポイントを挿入します
binding.pry
物事を見たい場所で(これは古典的なIDE環境でブレークポイントをトリガーするようなものです)
プログラムがヒットしたら
binding.pry
行の場合、プログラムのすべてのコンテキストを手元に置いて、pry replに直接アクセスできるため、周囲のすべてを探索したり、すべてのオブジェクトを調査したり、状態を変更したり、その場でコードを変更したりすることができます。
現在のメソッドのコードを変更することはできないと思うので、悲しいことに、実行する次の行を変更することはできません。しかし、良いRubyコードはとにかく単一行になる傾向があります;-)
例外の発生によるデバッグは、print
]ログステートメントを細かく調べるよりも--- [はるかに簡単であり、ほとんどのバグでは、一般的にはるかに速い = pry
やbyebug
のようなirbデバッガーを開くよりも。これらのツールは最初のステップではありません。
Exception
を発生させ、その結果を.inspect
発生させますfastestデバッグする方法Ruby(特にRails)コードは、メソッドまたはオブジェクト(例:raise
)で.inspect
を呼び出している間に、コードの実行パスに沿ってfoo
例外になります:
raise foo.inspect
上記のコードでは、-raise
がException
をトリガーし、コードの実行を停止し、オブジェクトに関する.inspect
情報を含むエラーメッセージを返します。デバッグしようとしている行の/ method(つまりfoo
)。
この手法は、quicklyオブジェクトまたはメソッドの検査(eg nil
?)や、特定の行内でコード行がまったく実行されているかどうかをすぐに確認する場合に便利です。コンテキスト。
byebug
またはpry
のようなデバッガーコード実行フローの状態に関する情報を取得した後にのみ、pry
やbyebug
などのRubygem irbデバッガーに移行することを検討してください。
問題をデバッグしようとするときは、常に次のことをお勧めします。!@#$ ingエラーメッセージ(RTFM)を読む
それはあなたが行動する前にエラーメッセージを読むことを意味します慎重にと完全にそれがあなたに伝えようとしていることを理解します。質問、この順序で、エラーメッセージを読むとき:
nil
?)スタックトレースでは、プロジェクトから来るコードの行(たとえば、Railsを使用している場合はapp/...
で始まる行)に特に注意を払ってください。 99%の時間は問題があなた自身のコードにあります。
この順序での解釈が重要である理由を説明するために...
ある時点で次のように実行されるコードを実行します。
@foo = Foo.new
...
@foo.bar
次のようなエラーが表示されます:
undefined method "bar" for Nil:nilClass
初心者はこのエラーを見て、問題はメソッドbar
がndefinedであると考えています。 それは違います。このエラーでは、重要な実際の部分は次のとおりです。
for Nil:nilClass
for Nil:nilClass
は@foo
がNilであることを意味します!@foo
はFoo
インスタンス変数ではありません! Nil
であるオブジェクトがあります。このエラーが表示された場合、クラス-bar
のオブジェクトに対してメソッドNil
が存在しないことを伝えるのは、単にRubyです。 (まあまあ!Foo
ではなくNil
クラスのオブジェクトにメソッドを使用しようとしているので)。
残念ながら、このエラーの記述方法(undefined method "bar" for Nil:nilClass
)により、このエラーはbar
がundefined
であることに関係していると簡単にintoされてしまいます。注意深く読んでいないと、このエラーにより、初心者がbar
のFoo
メソッドの詳細を誤って掘り下げ、オブジェクトが間違ったクラス(この場合はnil)であることを示唆するエラーの一部が完全に欠落します。これは間違いであり、エラーメッセージ全体を読むことで簡単に回避できます。
概要:
デバッグを開始する前に、常に慎重にentireエラーメッセージを読むを読んでください。つまり、常にエラーメッセージ内のオブジェクトのタイプclassをチェックしますfirst、次にそのmethods、beforeエラーが発生していると思われるスタックトレースまたはコード行の調査を開始します。これらの5秒は、5時間のフラストレーションを軽減します。
tl; dr:印刷ログを細かくしないでください:代わりに例外を発生させます。デバッグする前にエラーを注意深く読んでウサギの穴を避けてください。
可能な限り変数を出力します。 (これはprintfデバッグと呼ばれます)これを実行するには
STDERR.puts x.inspect
または
STDERR.puts "Variable x is #{x.inspect}"
これを入力しやすくしたい場合は、 exemplor gemを使用できます。
警告をオンにします。 Ruby
を実行している場合は、-w
スイッチ(Ruby -w script.rb
など)を使用して実行します。 irbから実行していて、1.9.2より前のRubyのバージョンを使用している場合は、セッションの開始時に$VERBOSE = true
と入力します。インスタンス変数のスペルを間違えた場合、警告が表示されると
警告:インスタンス変数
@valeus
が初期化されていません
バイナリチョップの概念を理解する(以下の引用は Practices of an Agile Developer )
問題空間を半分に分け、どちらに問題が含まれているかを確認します。次に、その半分を再び半分に分割し、繰り返します。
バイナリチョップで成功した場合、期待どおりの動作をしない単一の行があることに気付くかもしれません。例えば
[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) で、その機能を説明しています。
ただし、ドキュメントが役に立たない場合は、スクリプト全体が何をしていないのかではなく、特定の行がどのように機能していないのかについて質問することができれば、良い答えを得る可能性が高くなりますそうすべき。
すべてのものを削除します
2017年へようこそ^ _ ^
さて、新しいIDEを試すことに反対していなければ、freeで次のことができます。
launch.json
マクロを使用して"cwd"
およびand"program"
フィールドを使用するように{workspaceRoot}
を構成します"showDebuggerOutput"
というフィールドを追加し、true
に設定します"debug.allowBreakpointsEverywhere": true
としてデバッグ設定のすべての場所でブレークポイントを有効にしますvscode
;これは Visual Studio と同じではありません。それは無料で、軽量で、一般的に肯定的に評価されています。View->Extensions
.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 } ] }
File->Preferences->Settings
(または Ctrl, )そしてDebug
セクションに到達するまでスクロールします。それを展開し、"debug.allowBreakpointsEverywhere"
というフィールドを探します-そのフィールドを選択し、小さな鉛筆のようなアイコンをクリックして、true
に設定します。楽しいことをすべて行った後、ブレークポイントを設定し、2017年半ばと暗いテーマでこれに似たメニューでデバッグできるはずです: コールスタック、変数ビューアーなどの楽しいものすべて.
最大のPITAは、1)pre-reqをインストールすること、2).vscode\launch.json
ファイルを構成することを忘れないことです。将来のプロジェクトに荷物を追加する必要があるのは#2だけで、上記のような一般的な設定をコピーするだけです。おそらくもっと一般的な設定の場所がありますが、私は頭の外を知りません。
他のすべての答えはほとんどすべてをすでに与えています...ほんの少しの追加。
IDEに似たデバッガー(非CLI)が必要で、Vimをエディターとして使用することを恐れない場合は、 Vim Ruby Debugger のプラグインをお勧めします。
そのドキュメントは非常に単純なので、リンクをたどって参照してください。つまり、エディターの現在の行にブレークポイントを設定し、一時停止時に気の利いたウィンドウでローカル変数を表示し、ステップオーバー/ステップインすることができます。ほとんどすべての通常のデバッガー機能です。
私にとっては、このvimデバッガーを使用してRailsアプリをデバッグするのはとても楽しかったですが、 豊富なロガー機能 of Railsでほとんど不要になりました。
この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には、next
、step
、break
などの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.
-w
(警告)フラグをオンにするRuby 2.4.0の時点では、REPLプログラムの途中でIRB Rubyセッションを開始する方が簡単です。デバッグするプログラム内のポイントに次の行を配置します。
require 'irb'
binding.irb
Rubyコードを実行して、ローカル変数を出力できます。 Ctrl + Dまたはquit
と入力してREPLを終了し、Rubyプログラムを実行し続けます。
puts
およびp
を使用して、実行中のプログラムから値を出力することもできます。
現時点で適切なツールを選択してコードをデバッグするために、このビデオを強くお勧めします。
https://www.youtube.com/watch?v=GwgF8GcynV
個人的には、このビデオで2つの大きなトピックを取り上げます。
それは私の2セントです!
Rubyシェルスクリプトを簡単にデバッグするには、最初の行を次のように変更します。
#!/usr/bin/env Ruby
に:
#!/usr/bin/env Ruby -rdebug
その後、デバッガコンソールが表示されるたびに、次を選択できます。
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)
次に、プロセスのフォアグラウンドを確認します。
より適切に機能する場合は、lldb
をgdb
に置き換えます。所有していないプロセスをデバッグするには、Sudo
をプレフィックスとして付けます。
RubyMine を使用している場合、Rubyスクリプトのデバッグは簡単で簡単です。
Rubyスクリプトhello_world.rbがあるとします
以下のように6行目にブレークポイントを設定します。
これで、デバッガを起動してスクリプトを実行できます。
その後、実行がブレークポイントに達すると、変数などを検査できます。
さて、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
printfデバッグ
デバッグ技術については常に論争があり、一部の人はprint文によるデバッグを好む人もいれば、デバッガで掘り下げることを好む人もいます。
両方のアプローチを試すことをお勧めします。
実際、古いUnixの男性の1人は最近、printfデバッグがいくつかの点で彼にとってより速い方法であると言った。
しかし、ある仕事を始めたばかりで、大量のコードを理解する必要がある場合は、そこに足を踏み入れ、いくつかのブレークポイントをあちこちに置いて、それがどのように機能するかを理解することが本当に便利です。
コードがどのように織られているかを理解する必要があります。
あなたが他の人々のソフトウェアに慣れていない場合、それはあなたがそこをステップスルーするのに役立つかもしれません。
彼らが巧妙な方法でそれを整理したかどうか、またはそれがたわごとの束であるかどうかすぐにわかります。
さまざまな機能を持つ多くのデバッガがあり、それらに基づいて選択を行います。私の優先順位は pry-moves で満足しました:
すべてのデバッガの母は、普通の古い印刷画面です。ほとんどの場合、おそらくいくつかの単純なオブジェクトのみを検査する必要があります。すばやく簡単な方法は次のとおりです。
@result = fetch_result
p "--------------------------"
p @result
これにより、@ resultの内容が簡単に識別できるように、先頭に行を付けてSTDOUTに出力されます。
ボーナスRailsのようなオートロード/リロード可能なフレームワークを使用する場合、アプリを再起動する必要さえありません。 (フレームワーク固有の設定により、デバッグしているコードがリロードされない限り)
これは私のユースケースの90%で機能すると思います。 Ruby-debugを使用することもできますが、ほとんどの場合それはやり過ぎです。