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 pry0.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 ..
PrySaya byebughebat, tetapi bukan sebagai langkah pertama Anda saat debugging. Dalam kebanyakan kasus, mengajukan pengecualian dengan raise object.inspectakan 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 debuggerkode.
-r debugadalah sampah?
facetsdalam persyaratan permata, dan tidak berhasil. Untuk aplikasi Rails kuno ruby-debugagak 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 melaluiprintpernyataan log, dan untuk sebagian besar bug, yang umumnya jauh lebih cepat daripada membuka sebuah debugger irb sepertipryataubyebug. Alat-alat itu tidak harus selalu menjadi langkah pertama Anda.
Exceptionlalu dan .inspecthasilnyaCara tercepat untuk men-debug kode Ruby (terutama Rails) adalah dengan raisepengecualian di sepanjang jalur eksekusi kode Anda saat memanggil .inspectmetode atau objek (misalnya foo):
raise foo.inspect
Dalam kode di atas, raisememicu sebuah Exceptionyang menghentikan eksekusi kode Anda , dan mengembalikan pesan kesalahan yang dengan mudah berisi .inspectinformasi 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 ataupryHanya setelah Anda memiliki informasi tentang keadaan alur eksekusi kode Anda, sebaiknya Anda mempertimbangkan untuk pindah ke debugger seperti, pryatau di byebugmana 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 barini tidak terdefinisi . Ini bukan. Dalam kesalahan ini, bagian nyata yang penting adalah:
for Nil:nilClass
for Nil:nilClassberarti itu @fooNihil! @foobukan Foovariabel instan! Anda memiliki objek itu Nil. Ketika Anda melihat kesalahan ini, itu hanya ruby mencoba untuk memberi tahu Anda bahwa metode barini tidak ada untuk objek kelas Nil. (yah! Karena kami mencoba menggunakan metode untuk objek kelas Footidak Nil).
Sayangnya, karena cara kesalahan ini ditulis ( undefined method "bar" for Nil:nilClass) mudah untuk diperdaya untuk berpikir bahwa kesalahan ini berkaitan dengan barkeberadaan undefined. Ketika tidak membaca dengan cermat kesalahan ini menyebabkan pemula secara keliru menggali rincian barmetode 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 rubykemudian jalankan dengan -wsaklar (misalnya ruby -w script.rb). Jika Anda menjalankannya dari irb, dan Anda menggunakan versi ruby sebelum 1.9.2, ketikkan $VERBOSE = truedi awal sesi Anda. Jika Anda salah mengeja variabel instan, setelah peringatan muncul, Anda akan mendapatkannya
peringatan: variabel instance
@valeustidak 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 Arraybawahnya (jika Anda tidak tahu apa kelasnya [1, 2, 3], ketik [1, 2, 3].classirb), 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.jsonuntuk menggunakan "cwd"dan dan "program" bidang menggunakan {workspaceRoot}makro"showDebuggerOutput"dan setel ketrue"debug.allowBreakpointsEverywhere": truevscode; ini tidak sama dengan Visual Studio . Ini gratis, ringan, dan umumnya dianggap positif.View->Extensions.vscodedan di sana kami akan tetapi file yang disebut di launch.jsonmana 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 Debugbagian. 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.jsonfile. 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, stepdan 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.
-wbendera (peringatan)irbadalah 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:
cuntuk Lanjutkan (ke Pengecualian berikutnya, breakpoint atau baris dengan:) debugger,n untuk baris berikutnya,w/ whereuntuk 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/ gdbsuka:
echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -nf ruby)
dan kemudian periksa latar depan proses Anda.
Ganti lldbdengan gdbjika berfungsi lebih baik. Awalan dengan sudomen-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 quituntuk mengakhiri REPL dan biarkan program Ruby tetap berjalan.
Anda juga dapat menggunakan putsdan pmencetak 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: