Saya menyalin kode Ruby berikut ini dari Internet dan membuat beberapa perubahan tetapi tidak berhasil.
Apa yang bisa saya lakukan untuk men-debug program sendiri?
Saya menyalin kode Ruby berikut ini dari Internet dan membuat beberapa perubahan tetapi tidak berhasil.
Apa yang bisa saya lakukan untuk men-debug program sendiri?
Jawaban:
Instal melalui:
$ gem install pry
$ pry
Kemudian tambahkan:
require 'pry'; binding.pry
ke dalam program Anda.
Pada pry
0.12.2 Namun, ada perintah ada navigasi seperti next
, break
, dll Beberapa permata lainnya juga menyediakan ini, lihat misalnya pry-byedebug
.
binding.pry
. Itu juga dilengkapi dengan penyelesaian warna, pencarian dokumentasi, dan kemungkinan untuk secara dinamis mengedit dan memuat kembali suatu metode ..
Pry
Saya byebug
hebat, tetapi bukan sebagai langkah pertama Anda saat debugging. Dalam kebanyakan kasus, mengajukan pengecualian dengan raise object.inspect
akan menyelesaikan masalah Anda lebih cepat daripada membuka sesi IRB. Saya sarankan hanya menggunakan konsol debugger sekali lagi solusi sederhana seperti menaikkan pengecualian tidak dapat menyelesaikan masalah Anda.
pry
? Saya tidak dapat menemukan cara melakukannya; dan itulah yang saya harapkan dari debugger.
Di Ruby:
ruby -rdebug myscript.rb
kemudian,
b <line>
: menempatkan break-point n(ext)
atau s(tep)
danc(ontinue)
p(uts)
untuk tampilan(seperti perl debug)
In Rails: Luncurkan server dengan
script/server --debugger
dan tambahkan debugger
kode.
-r debug
adalah sampah?
facets
dalam persyaratan permata, dan tidak berhasil. Untuk aplikasi Rails kuno ruby-debug
agak buruk tetapi menyelesaikan pekerjaan.
Direkomendasikan sebagai pegangan tangga: gunakan pry! Saya hanya bisa menyetujui ini.
pry adalah pengganti yang jauh lebih baik daripada irb.
Anda perlu menambahkan
require 'pry'
ke file sumber Anda dan kemudian masukkan breakpoint dalam kode sumber Anda dengan menambahkan
binding.pry
di tempat Anda ingin melihat hal-hal (ini seperti memicu breakpoint di lingkungan IDE klasik)
Setelah program Anda menyentuh
binding.pry
baris, Anda akan dilemparkan ke dalam pry repl, dengan semua konteks program Anda di tangan, sehingga Anda dapat menjelajahi segala sesuatu di sekitar, menyelidiki semua objek, mengubah keadaan, dan bahkan mengubah kode dengan cepat.
Saya percaya Anda tidak dapat mengubah kode metode yang Anda gunakan saat ini, jadi Anda sedihnya tidak dapat mengubah baris berikutnya yang akan dieksekusi. Tetapi kode ruby yang baik cenderung menjadi satu baris ;-)
Debugging dengan menaikkan pengecualian adalah jauh lebih mudah daripada menyipitkan mata melaluiprint
pernyataan log, dan untuk sebagian besar bug, yang umumnya jauh lebih cepat daripada membuka sebuah debugger irb sepertipry
ataubyebug
. Alat-alat itu tidak harus selalu menjadi langkah pertama Anda.
Exception
lalu dan .inspect
hasilnyaCara tercepat untuk men-debug kode Ruby (terutama Rails) adalah dengan raise
pengecualian di sepanjang jalur eksekusi kode Anda saat memanggil .inspect
metode atau objek (misalnya foo
):
raise foo.inspect
Dalam kode di atas, raise
memicu sebuah Exception
yang menghentikan eksekusi kode Anda , dan mengembalikan pesan kesalahan yang dengan mudah berisi .inspect
informasi tentang objek / metode (yaitufoo
) pada baris yang Anda coba debug.
Teknik ini berguna untuk dengan cepat memeriksa suatu objek atau metode ( misalnya apakah itu nil
? ) Dan untuk segera mengkonfirmasikan apakah baris kode bahkan mendapatkan dieksekusi sama sekali dalam konteks tertentu.
byebug
ataupry
Hanya setelah Anda memiliki informasi tentang keadaan alur eksekusi kode Anda, sebaiknya Anda mempertimbangkan untuk pindah ke debugger seperti, pry
atau di byebug
mana Anda dapat mempelajari lebih dalam tentang keadaan objek dalam jalur eksekusi Anda.
Ketika Anda mencoba men-debug masalah, saran yang baik adalah untuk selalu: Baca The! @ # $ Ing Pesan Kesalahan (RTFM)
Itu berarti membaca pesan kesalahan dengan hati - hati dan sepenuhnya sebelum bertindak sehingga Anda mengerti apa yang ingin disampaikannya kepada Anda. Saat Anda men-debug, ajukan pertanyaan mental berikut, dalam urutan ini , saat membaca pesan kesalahan:
nil
? ) Dalam jejak tumpukan perhatikan baris kode yang berasal dari proyek Anda (misalnya, baris yang dimulai dengan app/...
jika Anda menggunakan Rails). 99% dari waktu masalahnya adalah dengan kode Anda sendiri.
Untuk mengilustrasikan mengapa menafsirkan dalam urutan ini penting ...
Anda menjalankan kode yang pada titik tertentu dijalankan seperti itu:
@foo = Foo.new
...
@foo.bar
dan Anda mendapatkan kesalahan yang menyatakan:
undefined method "bar" for Nil:nilClass
Pemula melihat kesalahan ini dan berpikir masalahnya adalah metode bar
ini tidak terdefinisi . Ini bukan. Dalam kesalahan ini, bagian nyata yang penting adalah:
for Nil:nilClass
for Nil:nilClass
berarti itu @foo
Nihil! @foo
bukan Foo
variabel instan! Anda memiliki objek itu Nil
. Ketika Anda melihat kesalahan ini, itu hanya ruby mencoba untuk memberi tahu Anda bahwa metode bar
ini tidak ada untuk objek kelas Nil
. (yah! Karena kami mencoba menggunakan metode untuk objek kelas Foo
tidak Nil
).
Sayangnya, karena cara kesalahan ini ditulis ( undefined method "bar" for Nil:nilClass
) mudah untuk diperdaya untuk berpikir bahwa kesalahan ini berkaitan dengan bar
keberadaan undefined
. Ketika tidak membaca dengan cermat kesalahan ini menyebabkan pemula secara keliru menggali rincian bar
metode iniFoo
, sepenuhnya melewatkan bagian dari kesalahan yang mengisyaratkan bahwa objek tersebut berasal dari kelas yang salah (dalam kasus ini: nil). Ini adalah kesalahan yang mudah dihindari dengan membaca pesan kesalahan secara keseluruhan.
Ringkasan:
Selalu hati-hati membaca seluruh pesan kesalahan sebelum memulai debugging apa pun. Itu berarti: Selalu periksa tipe kelas objek dalam pesan kesalahan terlebih dahulu , lalu metode - metodenya , sebelum Anda mulai menjalankan tumpukan kode atau baris kode apa pun yang menurut Anda kemungkinan terjadi kesalahan. 5 detik itu bisa menghemat 5 jam frustrasi.
tl; dr: Jangan menyipit di log cetak: naikkan pengecualian atau gunakan debugger irb sebagai gantinya. Hindari lubang kelinci dengan membaca kesalahan dengan cermat sebelum melakukan debug.
Cetak variabel bila memungkinkan. (Ini disebut printf debugging) Anda dapat melakukan ini dengan menjalankan
STDERR.puts x.inspect
atau
STDERR.puts "Variable x is #{x.inspect}"
Jika Anda ingin membuat ini lebih mudah untuk mengetik, maka Anda mungkin ingin menggunakan exemplor permata.
Aktifkan peringatan. Jika Anda menjalankan ruby
kemudian jalankan dengan -w
saklar (misalnya ruby -w script.rb
). Jika Anda menjalankannya dari irb, dan Anda menggunakan versi ruby sebelum 1.9.2, ketikkan $VERBOSE = true
di awal sesi Anda. Jika Anda salah mengeja variabel instan, setelah peringatan muncul, Anda akan mendapatkannya
peringatan: variabel instance
@valeus
tidak diinisialisasi
Memahami konsep pemotongan biner (kutipan berikut berasal dari Praktik Pengembang Agile )
Bagilah ruang masalahnya menjadi dua, dan lihat bagian mana yang berisi masalahnya. Kemudian bagi setengah menjadi dua lagi, dan ulangi.
Jika Anda berhasil dengan pemotongan biner, Anda mungkin menemukan bahwa ada satu baris yang tidak melakukan apa yang Anda harapkan. Sebagai contoh
[1, 2, 3].include?([1,2])
memberikan nilai false
, meskipun Anda akan berpikir itu akan kembali true
. Dalam hal ini, Anda mungkin ingin melihat dokumentasi. Situs web untuk dokumentasi termasuk ruby-doc.org , atau APIdock . Dalam kasus yang terakhir, Anda akan mengetik di include?
sebelah kaca pembesar di dekat sudut kanan atas, pilih include?
yang di Array
bawahnya (jika Anda tidak tahu apa kelasnya [1, 2, 3]
, ketik [1, 2, 3].class
irb), dan Anda bisa memasukkan? (Array) , yang menjelaskan apa yang dilakukannya.
Namun, jika dokumentasi tidak membantu, Anda lebih mungkin mendapatkan jawaban yang baik jika Anda dapat mengajukan pertanyaan tentang bagaimana baris tertentu tidak melakukan apa yang seharusnya, daripada mengapa seluruh skrip tidak melakukan apa Itu harus.
menghapus semua hal
Selamat datang di 2017 ^ _ ^
Oke, jadi jika Anda tidak menentang untuk mencoba IDE baru, Anda dapat melakukan hal berikut secara gratis .
launch.json
untuk menggunakan "cwd"
dan dan "program"
bidang menggunakan {workspaceRoot}
makro"showDebuggerOutput"
dan setel ketrue
"debug.allowBreakpointsEverywhere": true
vscode
; ini tidak sama dengan Visual Studio . Ini gratis, ringan, dan umumnya dianggap positif.View->Extensions
.vscode
dan di sana kami akan tetapi file yang disebut di launch.json
mana kami akan menyimpan beberapa opsi konfigurasi.
launch.json
isi
{
"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
(atau Ctrl,) dan gulir sampai Anda mencapai Debug
bagian. Luaskan dan cari bidang yang disebut "debug.allowBreakpointsEverywhere"
- pilih bidang itu dan klik ikon yang tampak seperti pensil dan atur true
.Setelah melakukan semua hal yang menyenangkan, Anda harus dapat mengatur breakpoint dan debug dalam menu yang mirip dengan ini untuk pertengahan 2017 dan tema yang lebih gelap: dengan semua hal menyenangkan seperti tumpukan panggilan, penampil variabel, dll.
PITA terbesar adalah 1) menginstal pre-reqs dan 2) Mengingat untuk mengkonfigurasi .vscode\launch.json
file. Hanya # 2 yang dapat menambahkan bagasi apa pun ke proyek-proyek masa depan, dan Anda hanya dapat menyalin konfigurasi yang cukup umum seperti yang tercantum di atas. Mungkin ada lokasi konfigurasi yang lebih umum, tetapi saya tidak tahu dari atas kepala saya.
Saya sangat merekomendasikan video ini, untuk memilih alat yang tepat saat ini untuk men-debug kode kami.
https://www.youtube.com/watch?v=GwgF8GcynV0
Secara pribadi, saya akan menyoroti dua topik besar dalam video ini.
Itu dua sen ku!
Semua jawaban lain sudah memberikan hampir semuanya ... Hanya sedikit tambahan.
Jika Anda ingin lebih banyak debugger seperti IDE (non-CLI) dan tidak takut menggunakan Vim sebagai editor, saya sarankan plugin Vim Ruby Debugger untuk itu.
Dokumentasinya sangat mudah, jadi ikuti tautannya dan lihat. Singkatnya, ini memungkinkan Anda untuk mengatur breakpoint pada baris saat ini di editor, melihat variabel lokal di jendela bagus pada jeda, melangkahi / masuk - hampir semua fitur debugger biasa.
Bagi saya itu cukup menyenangkan untuk menggunakan debugger vim ini untuk debugging aplikasi Rails, meskipun kemampuan logger kaya Rails hampir menghilangkan kebutuhan untuk itu.
Saya baru saja menemukan permata ini (mengubah Pry menjadi debugger untuk MRI Ruby 2.0+)
https://github.com/deivid-rodriguez/pry-byebug
Instal dengan:
gem install pry-byebug
kemudian gunakan persis seperti pry
, tandai baris yang ingin Anda hancurkan di:
require 'pry'; binding.pry
Namun tidak seperti vanilla pry, permata ini memiliki beberapa perintah navigasi seperti GDB seperti next
, step
dan break
:
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
bendera (peringatan)irb
adalah tempat awal yang bagus. Coba gunakan irb dengan potongan kecil yang dipertanyakan. Saya suka ruby-debug (ruby-debug19 untuk Ruby 1.9+) karena membuatnya mudah untuk menghentikan program yang sedang berjalan, memeriksa variabel, jatuh ke IRB, kemudian terus berjalan.
Untuk dengan mudah men-debug skrip shell Ruby, cukup ubah baris pertama dari:
#!/usr/bin/env ruby
untuk:
#!/usr/bin/env ruby -rdebug
Kemudian setiap kali ketika konsol debugger ditampilkan, Anda dapat memilih:
c
untuk Lanjutkan (ke Pengecualian berikutnya, breakpoint atau baris dengan:) debugger
,n
untuk baris berikutnya,w
/ where
untuk menampilkan bingkai / panggilan stack,l
untuk Menampilkan kode saat ini,cat
untuk menunjukkan titik tangkapan.h
untuk bantuan lebih lanjutLihat juga: Debugging dengan ruby-debug , pintasan kunci untuk ruby-debug gem .
Jika skrip hang dan Anda perlu backtrace, coba gunakan lldb
/ gdb
suka:
echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -nf ruby)
dan kemudian periksa latar depan proses Anda.
Ganti lldb
dengan gdb
jika berfungsi lebih baik. Awalan dengan sudo
men-debug proses yang tidak dimiliki.
Pada Ruby 2.4.0, lebih mudah untuk memulai sesi IRB REPL di tengah setiap program Ruby. Masukkan baris-baris ini pada titik di program yang ingin Anda debug:
require 'irb'
binding.irb
Anda dapat menjalankan kode Ruby dan mencetak variabel lokal. Ketik Ctrl + D atau quit
untuk mengakhiri REPL dan biarkan program Ruby tetap berjalan.
Anda juga dapat menggunakan puts
dan p
mencetak nilai-nilai dari program Anda saat program sedang berjalan.
Jika Anda menggunakan RubyMine , men -debug skrip ruby sederhana dan mudah.
Misalkan Anda memiliki skrip Ruby hello_world.rb
Tetapkan breakpoint pada baris 6 seperti di bawah ini.
Sekarang Anda bisa memulai debugger untuk menjalankan skrip:
Kemudian ketika eksekusi mencapai breakpoint, Anda akan dapat memeriksa variabel, dll.
printf debugging
Selalu ada kontroversi seputar teknik debugging, beberapa orang suka men-debug dengan pernyataan cetak, beberapa yang lain suka menggali lebih dalam dengan debugger.
Saya sarankan Anda mencoba kedua pendekatan.
Sebenarnya salah satu pria Unix lama baru-baru ini mengatakan, bahwa debugging printf adalah cara yang lebih cepat untuknya di beberapa titik.
Tetapi jika Anda baru dalam suatu pekerjaan dan perlu memahami segumpal besar kode, maka sangat berguna untuk melangkah di sana, meletakkan beberapa breakpoints di sana-sini, mengikuti cara kerjanya.
Seharusnya memberi Anda beberapa pemahaman tentang bagaimana kode ditenun.
Jika Anda baru mengenal beberapa perangkat lunak orang lain, ini mungkin membantu Anda melangkah ke sana.
Anda akan segera mengetahui apakah mereka mengaturnya dengan cara yang cerdas, atau jika itu hanya omong kosong.
Nah, ruby standard lib memiliki debugger konsol gdb-like yang mudah digunakan: http://ruby-doc.org/stdlib-2.1.0/libdoc/debug/rdoc/DEBUGGER__.html Tidak perlu memasang permata tambahan. Script rel juga dapat di-debug seperti itu.
misalnya
def say(word)
require 'debug'
puts word
end
Induk semua debugger adalah layar cetak lama biasa. Sebagian besar waktu, Anda mungkin hanya ingin memeriksa beberapa objek sederhana, cara cepat dan mudah adalah seperti ini:
@result = fetch_result
p "--------------------------"
p @result
Ini akan mencetak konten @result ke STDOUT dengan garis di depan untuk memudahkan identifikasi.
Bonus jika Anda menggunakan kerangka kerja kemampuan memuat / memuat ulang otomatis seperti Rails, Anda bahkan tidak perlu memulai ulang aplikasi Anda. (Kecuali jika kode yang Anda debug tidak dimuat ulang karena pengaturan kerangka spesifik)
Saya menemukan ini berfungsi untuk 90% dari use case untuk saya. Anda juga dapat menggunakan ruby-debug, tetapi saya merasa hal itu terlalu banyak menghabiskan waktu.
Ada banyak debugger dengan fitur berbeda, berdasarkan yang Anda pilih. Prioritas saya puas dengan pry-move yaitu: