ฉันคัดลอกรหัส Ruby ต่อไปนี้จากอินเทอร์เน็ตและทำการเปลี่ยนแปลงเล็กน้อย แต่ไม่ได้ผล
ฉันจะทำอย่างไรเพื่อแก้ไขข้อบกพร่องของโปรแกรมด้วยตัวเอง
ฉันคัดลอกรหัส Ruby ต่อไปนี้จากอินเทอร์เน็ตและทำการเปลี่ยนแปลงเล็กน้อย แต่ไม่ได้ผล
ฉันจะทำอย่างไรเพื่อแก้ไขข้อบกพร่องของโปรแกรมด้วยตัวเอง
คำตอบ:
ติดตั้งผ่าน:
$ gem install pry
$ pry
จากนั้นเพิ่ม:
require 'pry'; binding.pry
เข้าสู่โปรแกรมของคุณ
ในฐานะของpry
0.12.2 แต่มีคำสั่งนำทางไม่มีเช่นnext
, break
ฯลฯ บางอัญมณีอื่น ๆ pry-byedebug
นอกจากนี้ยังให้บริการนี้ดูตัวอย่าง
binding.pry
เมื่อติดตั้งและจำเป็นต้องใช้ในโปรแกรมของคุณตั้งค่าเบรกพอยต์เป็นเรื่องง่ายเหมือนการเขียน นอกจากนี้ยังมาพร้อมกับการเติมสีการค้นหาเอกสารและความเป็นไปได้ในการแก้ไขและโหลดวิธีการใหม่ ..
Pry
/ byebug
ดีมาก แต่ไม่เป็นขั้นตอนที่ 1 ของคุณเมื่อทำการดีบั๊ก ในกรณีส่วนใหญ่การเพิ่มข้อยกเว้นด้วยraise object.inspect
จะช่วยแก้ปัญหาของคุณได้เร็วกว่าการเปิดเซสชัน irb ฉันแนะนำให้ใช้คอนโซลดีบั๊กเพียงครั้งเดียวโซลูชันที่ง่ายขึ้นเช่นการเพิ่มข้อยกเว้นไม่สามารถแก้ปัญหาของคุณได้
pry
หรือไม่ ฉันหาวิธีทำไม่ได้ และนั่นคือสิ่งที่ฉันคาดหวังจากตัวดีบัก
ในทับทิม:
ruby -rdebug myscript.rb
แล้ว
b <line>
: ใส่จุดพัก n(ext)
หรือs(tep)
และc(ontinue)
p(uts)
สำหรับการแสดงผล(เช่น perl debug)
ใน Rails: เรียกใช้เซิร์ฟเวอร์ด้วย
script/server --debugger
และเพิ่มdebugger
ในรหัส
-r debug
ขยะ
facets
ในอัญมณีเฉพาะรุ่นและไม่ประสบความสำเร็จ สำหรับแอพ Rails โบราณruby-debug
นั้นค่อนข้างน่ารังเกียจ แต่ก็ทำงานเสร็จแล้ว
ตามที่แนะนำ banister: ใช้แงะ! ฉันเห็นด้วยกับสิ่งนี้เท่านั้น
แงะเป็นแบบจำลองที่ดีกว่า IRB
คุณต้องเพิ่ม
require 'pry'
ไปยังไฟล์ต้นฉบับของคุณแล้วใส่เบรกพอยต์ในซอร์สโค้ดของคุณโดยการเพิ่ม
binding.pry
ในสถานที่ที่คุณต้องการดูสิ่งต่าง ๆ (นี่เป็นเหมือนจุดกระตุ้นจุดพักในสภาพแวดล้อม IDE ดั้งเดิม)
เมื่อโปรแกรมของคุณฮิต
binding.pry
บรรทัดคุณจะถูกโยนลงใน pry repl โดยที่บริบททั้งหมดของโปรแกรมของคุณอยู่ในมือเพื่อให้คุณสามารถสำรวจทุกสิ่งรอบ ๆ ตรวจสอบวัตถุทั้งหมดเปลี่ยนสถานะและแม้แต่เปลี่ยนรหัสได้ทันที
ฉันเชื่อว่าคุณไม่สามารถเปลี่ยนรหัสของวิธีการที่คุณอยู่ในขณะนี้ดังนั้นคุณจึงไม่สามารถเปลี่ยนบรรทัดถัดไปที่จะดำเนินการได้ แต่รหัสทับทิมที่ดีมักจะเป็นบรรทัดเดียวอย่างไรก็ตาม ;-)
แก้จุดบกพร่องโดยการเพิ่มข้อยกเว้นคือไกลได้ง่ายขึ้นกว่า squinting ผ่านprint
งบบันทึกและข้อบกพร่องมากที่สุดโดยทั่วไปของมันได้เร็วขึ้นมากกว่าการเปิดขึ้นดีบัก IRB เหมือนหรือpry
byebug
เครื่องมือเหล่านั้นไม่ควรเป็นขั้นตอนแรกของคุณเสมอไป
Exception
แล้วและ.inspect
ผลของมันเร็วที่สุดวิธีที่จะแก้ปัญหาทับทิม (โดยเฉพาะ Rails) รหัสคือการraise
มีข้อยกเว้นตามเส้นทางการดำเนินการของรหัสของคุณในขณะที่โทร.inspect
กับวิธีการหรือวัตถุ (เช่นfoo
):
raise foo.inspect
ในโค้ดด้านบนraise
ทริกเกอร์สิ่งException
ที่หยุดการทำงานของรหัสของคุณและส่งกลับข้อความแสดงข้อผิดพลาดที่มี.inspect
ข้อมูลเกี่ยวกับวัตถุ / วิธีการ (เช่นfoo
) ในบรรทัดที่คุณพยายามตรวจแก้จุดบกพร่อง
เทคนิคนี้มีประโยชน์สำหรับการตรวจสอบวัตถุหรือวิธีการอย่างรวดเร็ว ( เช่นมันได้nil
หรือไม่ ) และเพื่อยืนยันทันทีว่าบรรทัดของรหัสกำลังถูกดำเนินการเลยในบริบทที่กำหนดหรือไม่
byebug
orpry
หลังจากที่คุณมีข้อมูลเกี่ยวกับสถานะของการประมวลผลโค้ดของคุณแล้วคุณควรพิจารณาย้ายไปที่ดีบั๊ก irb gem rubb เช่นpry
หรือbyebug
ที่ที่คุณสามารถเจาะลึกเข้าไปในสถานะของวัตถุภายในเส้นทางการทำงานของคุณ
เมื่อคุณพยายามที่จะดีบักปัญหาคำแนะนำที่ดีคือให้ อ่านข้อความข้อผิดพลาด! @ # $ ing (RTFM)
นั่นหมายถึงการอ่านข้อความแสดงข้อผิดพลาดอย่างรอบคอบและครบถ้วนก่อนที่จะดำเนินการเพื่อให้คุณเข้าใจในสิ่งที่พยายามบอกคุณ เมื่อคุณดีบักถามคำถามต่อไปนี้ตามลำดับเมื่ออ่านข้อความแสดงข้อผิดพลาด:
nil
อย่างไร ) ในการติดตามสแต็กให้ความสนใจเป็นพิเศษกับบรรทัดของรหัสที่มาจากโครงการของคุณ (เช่นบรรทัดที่ขึ้นต้นด้วยapp/...
ถ้าคุณใช้ Rails) 99% ของปัญหาที่เกิดขึ้นกับรหัสของคุณเอง
เพื่อแสดงให้เห็นว่าทำไมการตีความตามลำดับนี้จึงมีความสำคัญ ...
คุณรันโค้ดที่บางจุดดำเนินการเช่น:
@foo = Foo.new
...
@foo.bar
และคุณได้รับข้อผิดพลาดที่ระบุ:
undefined method "bar" for Nil:nilClass
เริ่มต้นเห็นข้อผิดพลาดนี้และคิดว่าปัญหาอยู่ว่าวิธีการที่bar
จะไม่ได้กำหนด มันไม่ใช่. ในข้อผิดพลาดนี้ส่วนที่แท้จริงที่สำคัญคือ:
for Nil:nilClass
for Nil:nilClass
หมายความว่านั่น@foo
คือไม่มี! @foo
ไม่ใช่Foo
ตัวแปรอินสแตนซ์! Nil
คุณมีวัตถุที่เป็น เมื่อคุณเห็นข้อผิดพลาดนี้ก็เพียงแค่ทับทิมพยายามที่จะบอกคุณว่าวิธีการที่ไม่ได้อยู่สำหรับวัตถุของชั้นเรียนbar
Nil
(ดีนะ! เนื่องจากเราพยายามใช้วิธีการสำหรับวัตถุของคลาสFoo
ไม่Nil
)
น่าเสียดายเนื่องจากข้อผิดพลาดนี้เขียน ( undefined method "bar" for Nil:nilClass
) มันง่ายที่จะถูกหลอกให้คิดว่าข้อผิดพลาดนี้เกี่ยวข้องกับbar
การเป็นundefined
อยู่ เมื่อไม่ได้อ่านอย่างระมัดระวังข้อผิดพลาดนี้ทำให้ผู้เริ่มต้นเข้าใจผิดอย่างละเอียดในรายละเอียดของbar
วิธีการFoo
นั้นหายไปอย่างสิ้นเชิงส่วนหนึ่งของข้อผิดพลาดที่บอกเป็นนัยว่าวัตถุนั้นเป็นคลาสที่ผิด (ในกรณีนี้: ไม่มี) เป็นความผิดพลาดที่หลีกเลี่ยงได้ง่ายโดยการอ่านข้อความผิดพลาดทั้งหมด
สรุป:
อ่านข้อผิดพลาดทั้งหมดอย่างรอบคอบก่อนที่จะเริ่มแก้ไขข้อบกพร่องใด ๆ ซึ่งหมายความว่า: โปรดตรวจสอบระดับประเภทของวัตถุในข้อผิดพลาดครั้งแรกแล้วมันวิธีการ , ก่อนที่คุณจะเริ่มสืบค้นลงใน stacktrace หรือบรรทัดของรหัสที่คุณคิดว่าข้อผิดพลาดอาจจะเกิดขึ้น 5 วินาทีนั้นสามารถช่วยให้คุณประหยัดเวลาได้ 5 ชั่วโมง
tl; dr:อย่าเหล่ที่บันทึกการพิมพ์: ยกข้อยกเว้นหรือใช้ตัวดีบัก irb แทน หลีกเลี่ยงหลุมกระต่ายโดยการอ่านข้อผิดพลาดอย่างรอบคอบก่อนทำการดีบั๊ก
พิมพ์ตัวแปรทุกครั้งที่ทำได้ (ซึ่งเรียกว่าการดีบัก printf) คุณสามารถทำได้โดยการเรียกใช้
STDERR.puts x.inspect
หรือ
STDERR.puts "Variable x is #{x.inspect}"
หากคุณต้องการที่จะทำให้ง่ายต่อการพิมพ์แล้วคุณอาจต้องการที่จะใช้exemplorอัญมณี
เปิดคำเตือน หากคุณใช้งานอยู่ให้ruby
รันด้วย-w
สวิตช์ (เช่นruby -w script.rb
) หากคุณเรียกใช้จาก irb และคุณใช้ทับทิมรุ่นก่อนหน้า 1.9.2 ให้พิมพ์$VERBOSE = true
ที่จุดเริ่มต้นเซสชันของคุณ หากคุณสะกดคำผิดตัวอย่างเช่นเมื่อคำเตือนอยู่ที่คุณจะได้รับ
คำเตือน: ตัวแปรอินสแตนซ์
@valeus
ไม่ได้เริ่มต้น
ทำความเข้าใจกับแนวคิดของไบนารีสับ (คำพูดต่อไปนี้มาจากการปฏิบัติของผู้พัฒนาแบบ Agile )
แบ่งพื้นที่ปัญหาออกเป็นสองส่วนและดูว่าครึ่งหนึ่งมีปัญหาใด จากนั้นแบ่งครึ่งครึ่งนั้นอีกครั้งแล้วทำซ้ำ
หากคุณประสบความสำเร็จกับไบนารีสับคุณอาจพบว่ามีบรรทัดเดียวที่ไม่ได้ทำในสิ่งที่คุณคาดหวังว่าจะทำ ตัวอย่างเช่น
[1, 2, 3].include?([1,2])
ให้ค่าของแม้ว่าคุณจะคิดว่ามันจะกลับมาfalse
true
ในกรณีนั้นคุณอาจต้องการดูเอกสารประกอบ เว็บไซต์สำหรับเอกสาร ได้แก่ruby-doc.orgหรือAPIdock ในกรณีหลังคุณจะพิมพ์include?
ถัดจากแว่นขยายใกล้มุมขวาบนเลือกสิ่งinclude?
ที่Array
อยู่ข้างใต้ (ถ้าคุณไม่รู้ว่าคลาส[1, 2, 3]
คืออะไรพิมพ์[1, 2, 3].class
irb) และคุณจะต้องรวมอะไรบ้าง (Array)ซึ่งอธิบายสิ่งที่มันทำ
อย่างไรก็ตามหากเอกสารไม่ช่วยให้คุณมีแนวโน้มที่จะได้รับคำตอบที่ดีถ้าคุณสามารถถามคำถามว่าบรรทัดที่ระบุไม่ทำในสิ่งที่ควรทำแทนที่จะเป็นว่าทำไมทั้งสคริปต์ไม่ทำสิ่งที่ มันควรจะ.
ลบทุกสิ่ง
ยินดีต้อนรับสู่ 2017 ^ _ ^
เอาล่ะดังนั้นถ้าคุณไม่เห็นด้วยกับการพยายามออก IDE ที่ใหม่ที่คุณสามารถทำสิ่งต่อไปนี้สำหรับฟรี
launch.json
จะใช้"cwd"
และและ "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
และตั้งค่าให้หลังจากทำทุกอย่างสนุกแล้วคุณควรจะสามารถตั้งค่าเบรกพอยต์และดีบักในเมนูที่คล้ายกับสิ่งนี้สำหรับกลางปี 2560 และชุดรูปแบบที่มืดกว่า: ด้วยสิ่งที่สนุกสนานเช่นสแตกการโทรของคุณตัวแสดงตัวแปร ฯลฯ
PITA ที่ใหญ่ที่สุดคือ 1) การติดตั้ง pre-reqs และ 2) การจำเพื่อกำหนดค่า.vscode\launch.json
ไฟล์ มีเพียง # 2 เท่านั้นที่ควรเพิ่มสัมภาระใด ๆ ในโครงการในอนาคตและคุณสามารถคัดลอกการกำหนดค่าทั่วไปพอเช่นที่ระบุไว้ข้างต้น อาจมีตำแหน่งปรับตั้งทั่วไปมากกว่า แต่ฉันไม่รู้ด้านบนของหัว
ฉันขอแนะนำวิดีโอนี้เพื่อเลือกเครื่องมือที่เหมาะสมในขณะนี้เพื่อแก้ปัญหารหัสของเรา
https://www.youtube.com/watch?v=GwgF8GcynV0
โดยส่วนตัวฉันจะเน้นสองหัวข้อใหญ่ในวิดีโอนี้
นั่นคือสองเซ็นต์ของฉัน!
คำตอบอื่น ๆ ทั้งหมดให้เกือบทุกอย่างแล้ว ... นอกจากนี้เล็กน้อย
หากคุณต้องการตัวดีบักคล้าย IDE (ไม่ใช่ CLI) และไม่กลัวการใช้ Vim เป็นตัวแก้ไขฉันขอแนะนำปลั๊กอินVim Ruby Debugger
เอกสารของมันค่อนข้างตรงไปตรงมาดังนั้นให้ไปที่ลิงค์และดู ในระยะสั้นจะช่วยให้คุณสามารถตั้งค่าเบรกพอยต์ที่บรรทัดปัจจุบันในการแก้ไขดูตัวแปรท้องถิ่นในหน้าต่างที่ดีเมื่อหยุดชั่วคราวก้าวข้าม / เข้า - คุณสมบัติการดีบักเกอร์เกือบทั้งหมด
สำหรับฉันมันเป็นเรื่องสนุกที่จะใช้ตัวแก้จุดบกพร่องนี้เพื่อการดีบักแอพ Rails แม้ว่าความสามารถในการบันทึกที่สมบูรณ์ของ Rails จะไม่จำเป็นต้องใช้มัน
ฉันเพิ่งค้นพบอัญมณีนี้ (เปลี่ยนแงะเป็นดีบักเกอร์สำหรับ MRI Ruby 2.0+)
https://github.com/deivid-rodriguez/pry-byebug
ติดตั้งด้วย:
gem install pry-byebug
จากนั้นใช้เหมือนpry
ทำเครื่องหมายบรรทัดที่คุณต้องการแบ่งที่:
require 'pry'; binding.pry
ซึ่งแตกต่างจากวานิลลาแงะ แต่อัญมณีนี้มีบางส่วน GDB-เช่นการนำคำสั่งที่สำคัญเช่นnext
, step
และ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
ตั้งค่าสถานะ (คำเตือน)irb
คือจุดเริ่มต้นที่ดี ลองใช้ irb กับชิ้นเล็ก ๆ ที่น่าสงสัย ฉันรัก ruby-debug (ruby-debug19 สำหรับ Ruby 1.9+) เพราะมันทำให้ง่ายต่อการหยุดโปรแกรมที่กำลังรันตรวจสอบตัวแปรวางลงใน irb จากนั้นทำงานต่อไป
หากต้องการดีบักสคริปต์ Ruby shell ง่ายๆเพียงแค่เปลี่ยนบรรทัดแรกจาก:
#!/usr/bin/env ruby
ถึง:
#!/usr/bin/env ruby -rdebug
จากนั้นทุกครั้งที่แสดงคอนโซลดีบักเกอร์คุณสามารถเลือก:
c
สำหรับการดำเนินการต่อไป (ไปข้อยกเว้นต่อไปเบรกพอยต์หรือสายด้วย: debugger
)n
สำหรับบรรทัดถัดไปw
/ where
เพื่อแสดงเฟรม / call stack,l
เพื่อแสดงรหัสปัจจุบันcat
เพื่อแสดง catchpointh
สำหรับความช่วยเหลือเพิ่มเติมดูเพิ่มเติม: Debugging กับทับทิมแก้ปัญหา , ทางลัดที่สำคัญสำหรับการแก้ปัญหาทับทิมอัญมณี
ในกรณีที่สคริปต์หยุดทำงานและคุณต้องการ backtrace ลองใช้lldb
/ gdb
like:
echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -nf ruby)
จากนั้นตรวจสอบกระบวนการทำงานเบื้องหน้าของคุณ
แทนที่lldb
ด้วยgdb
หากทำงานได้ดีขึ้น คำนำหน้าด้วยsudo
เพื่อดีบักกระบวนการที่ไม่ใช่เจ้าของ
ตั้งแต่ Ruby 2.4.0 การเริ่มเซสชัน IRB REPL ง่ายกว่าในช่วงกลางของโปรแกรม Ruby ใด ๆ วางบรรทัดเหล่านี้ไว้ตรงจุดในโปรแกรมที่คุณต้องการดีบัก:
require 'irb'
binding.irb
คุณสามารถเรียกใช้รหัส Ruby และพิมพ์ตัวแปรท้องถิ่น พิมพ์ Ctrl + D หรือquit
เพื่อจบ REPL และปล่อยให้โปรแกรม Ruby ทำงานต่อไป
คุณยังสามารถใช้puts
และp
พิมพ์ค่าจากโปรแกรมของคุณในขณะที่กำลังทำงาน
หากคุณใช้RubyMine การดีบักสคริปต์ ruby นั้นง่ายและตรงไปตรงมา
สมมติว่าคุณมีสคริปต์ Ruby hello_world.rb
ตั้งค่าเบรกพอยต์ที่บรรทัด 6 ดังนี้
ตอนนี้คุณสามารถเริ่มดีบักเกอร์เพื่อเรียกใช้สคริปต์:
จากนั้นเมื่อการดำเนินการถึงจุดหยุดคุณจะสามารถตรวจสอบตัวแปรและอื่น ๆ ได้
การดีบัก printf
มีการถกเถียงกันบ่อยครั้งเกี่ยวกับเทคนิคการดีบั๊กบางคนชอบที่จะดีบั๊กด้วยคำแถลงการพิมพ์บางคนชอบที่จะขุดลึกลงไปด้วยดีบั๊ก
ฉันขอแนะนำให้คุณลองทั้งสองวิธี
อันที่จริงคนหนึ่งใน Unix ที่มีอายุน้อยกล่าวว่าการดีบัก printf นั้นเป็นวิธีที่เร็วกว่าสำหรับเขาในบางจุด
แต่ถ้าคุณยังใหม่กับงานและต้องเข้าใจโค้ดขนาดใหญ่มันมีประโยชน์จริง ๆ ที่จะก้าวไปที่นั่นวางจุดพักที่นี่และที่นั่นไปพร้อมกับวิธีการทำงาน
มันควรจะให้คุณเข้าใจว่าโค้ดนั้นทอ
หากคุณยังใหม่กับซอฟต์แวร์ของคนอื่น ๆ มันอาจช่วยให้คุณก้าวผ่านไปได้
คุณจะรู้ได้อย่างรวดเร็วว่าพวกเขาจัดการมันด้วยวิธีที่ชาญฉลาดหรือไม่
lib มาตรฐาน ruby มีตัวแก้ไขคอนโซล gdb-like ที่ใช้งานง่าย: http://ruby-doc.org/stdlib-2.1.0/libdoc/debug/rdoc/DEBUGGER__.html ไม่จำเป็นต้องติดตั้งอัญมณีพิเศษใด ๆ สคริปต์ Rails สามารถ debugged ได้เช่นกัน
เช่น
def say(word)
require 'debug'
puts word
end
แม่ของดีบักเกอร์ทั้งหมดเป็นหน้าจอพิมพ์เก่าแบบธรรมดา ส่วนใหญ่คุณอาจต้องการตรวจสอบวัตถุง่าย ๆ บางอย่างเท่านั้นวิธีที่รวดเร็วและง่ายดายเป็นดังนี้:
@result = fetch_result
p "--------------------------"
p @result
สิ่งนี้จะพิมพ์เนื้อหาของ @result ไปยัง STDOUT โดยมีบรรทัดด้านหน้าเพื่อระบุตัวตนได้ง่าย
โบนัสถ้าคุณใช้เฟรมเวิร์กที่มีความสามารถในการโหลดอัตโนมัติ / โหลดเช่น Rails คุณไม่จำเป็นต้องรีสตาร์ทแอพ (ยกเว้นรหัสที่คุณกำลังดีบักจะไม่ถูกโหลดใหม่เนื่องจากการตั้งค่าเฉพาะของกรอบงาน)
ฉันคิดว่ามันใช้งานได้ 90% ของกรณีการใช้งานสำหรับฉัน คุณยังสามารถใช้ ruby-debug ได้ แต่ฉันพบว่ามันมากเกินไป
มี debuggers จำนวนมากที่มีคุณสมบัติแตกต่างกันตามที่คุณเลือก ลำดับความสำคัญของฉันพอใจกับการเคลื่อนไหวสอดรู้สอดเห็นซึ่ง: