Tôi đã sao chép mã Ruby sau từ Internet và thực hiện một vài thay đổi nhưng nó không hoạt động.
Tôi có thể làm gì để tự gỡ lỗi chương trình?
Tôi đã sao chép mã Ruby sau từ Internet và thực hiện một vài thay đổi nhưng nó không hoạt động.
Tôi có thể làm gì để tự gỡ lỗi chương trình?
Câu trả lời:
Cài đặt qua:
$ gem install pry
$ pry
Sau đó thêm:
require 'pry'; binding.pry
vào chương trình của bạn.
Tính đến pry
0.12.2 Tuy nhiên, có những lệnh không chuyển hướng như next
, break
vv Một số đá quý khác bổ sung cung cấp này, xem ví dụ pry-byedebug
.
binding.pry
. Nó cũng đi kèm với hoàn thành màu sắc, tra cứu tài liệu và khả năng tự động chỉnh sửa và tải lại một phương thức ..
Pry
/ byebug
là tuyệt vời, nhưng không phải là bước đầu tiên của bạn khi gỡ lỗi. Trong hầu hết các trường hợp, đưa ra một ngoại lệ với raise object.inspect
sẽ giải quyết vấn đề của bạn nhanh hơn là mở một phiên irb. Tôi khuyên bạn chỉ nên sử dụng trình gỡ lỗi giao diện điều khiển một khi các giải pháp đơn giản hơn như đưa ra một ngoại lệ không thể giải quyết vấn đề của bạn.
pry
? Tôi không thể tìm ra cách để làm điều đó; và đó là những gì tôi mong đợi của một trình sửa lỗi.
Trong Ruby:
ruby -rdebug myscript.rb
sau đó,
b <line>
: đặt điểm dừng n(ext)
hoặc s(tep)
vàc(ontinue)
p(uts)
Để trưng bày(như gỡ lỗi perl)
Trong Rails: Khởi chạy máy chủ với
script/server --debugger
và thêm debugger
vào mã.
-r debug
là rác?
facets
trong các yêu cầu đá quý, và đã không thành công. Đối với các ứng dụng Rails cổ ruby-debug
thì hơi khó chịu nhưng hoàn thành công việc.
Như lan can khuyến cáo: sử dụng pry! Tôi chỉ có thể đồng ý về điều này.
pry là một thay thế tốt hơn nhiều so với irb.
Bạn cần phải thêm
require 'pry'
vào tệp nguồn của bạn và sau đó chèn một điểm dừng trong mã nguồn của bạn bằng cách thêm
binding.pry
tại nơi bạn muốn xem xét mọi thứ (điều này giống như kích hoạt một điểm dừng trong môi trường IDE cổ điển)
Khi chương trình của bạn đạt
binding.pry
, bạn sẽ được ném ngay vào trò chơi thay thế, với tất cả bối cảnh chương trình của bạn ngay để bạn có thể khám phá mọi thứ xung quanh, điều tra tất cả các đối tượng, thay đổi trạng thái và thậm chí thay đổi mã khi đang di chuyển.
Tôi tin rằng bạn không thể thay đổi mã của phương thức mà bạn hiện đang sử dụng, vì vậy bạn có thể buồn thay đổi dòng tiếp theo sẽ được thực thi. Nhưng mã ruby tốt có xu hướng là một dòng duy nhất ;-)
Gỡ rối bằng cách tăng trường hợp ngoại lệ là xa dễ dàng hơn so với nheo mắt quaprint
báo cáo nhật ký, và cho hầu hết các lỗi, nó thường nhanh hơn nhiều so với mở ra một debugger IRB nhưpry
haybyebug
. Những công cụ đó không phải luôn luôn là bước đầu tiên của bạn.
Exception
sau đó và.inspect
kết quả của nóCách nhanh nhất để gỡ lỗi mã Ruby (đặc biệt là Rails) là raise
ngoại lệ dọc theo đường dẫn thực thi mã của bạn trong khi gọi .inspect
phương thức hoặc đối tượng (ví dụ foo
):
raise foo.inspect
Trong đoạn mã trên, raise
gây nên một Exception
mà tạm dừng thực hiện mã của bạn , và trả về một thông báo lỗi thuận tiện chứa .inspect
thông tin về các đối tượng / phương pháp (ví dụ:foo
) trên dòng mà bạn đang cố gắng để gỡ lỗi.
Kỹ thuật này rất hữu ích để kiểm tra nhanh một đối tượng hoặc phương thức ( ví dụ như vậy nil
? ) Và để xác nhận ngay lập tức liệu một dòng mã thậm chí có được thực thi hay không trong một bối cảnh cụ thể.
byebug
hoặcpry
Chỉ sau khi bạn có thông tin về trạng thái của luồng thực thi mã của mình, bạn mới nên xem xét chuyển sang trình gỡ lỗi ruby gem irb pry
hoặc byebug
nơi bạn có thể tìm hiểu sâu hơn về trạng thái của các đối tượng trong đường dẫn thực thi của mình.
Khi bạn đang cố gắng gỡ lỗi một vấn đề, lời khuyên tốt là luôn luôn: Đọc Thông báo lỗi! @ # $ Ing (RTFM)
Điều đó có nghĩa là đọc các thông báo lỗi một cách cẩn thận và hoàn toàn trước khi hành động để bạn hiểu những gì nó đang cố nói với bạn. Khi bạn gỡ lỗi, hãy hỏi các câu hỏi tinh thần sau, theo thứ tự này , khi đọc thông báo lỗi:
nil
? ) Trong ngăn xếp theo dõi, đặc biệt chú ý đến các dòng mã xuất phát từ dự án của bạn (ví dụ: các dòng bắt đầu bằng app/...
nếu bạn đang sử dụng Rails). 99% thời gian xảy ra sự cố với mã của riêng bạn.
Để minh họa tại sao việc diễn giải theo thứ tự này lại quan trọng ...
Bạn thực thi mã mà tại một số điểm thực thi như vậy:
@foo = Foo.new
...
@foo.bar
và bạn nhận được một lỗi thông báo:
undefined method "bar" for Nil:nilClass
Người mới bắt đầu thấy lỗi này và nghĩ rằng vấn đề là phương pháp bar
này không được xác định . Nó không thể. Trong lỗi này, phần thực sự quan trọng là:
for Nil:nilClass
for Nil:nilClass
có nghĩa @foo
là Nil! @foo
không phải là một Foo
biến thể! Bạn có một đối tượng đó là Nil
. Khi bạn thấy lỗi này, nó chỉ đơn giản là ruby cố gắng nói với bạn rằng phương thức bar
này không tồn tại cho các đối tượng của lớp Nil
. (duh! vì chúng tôi đang cố gắng sử dụng một phương thức cho một đối tượng của lớp Foo
không Nil
).
Thật không may, do cách lỗi này được viết ( undefined method "bar" for Nil:nilClass
) nó dễ dàng bị lừa vào suy nghĩ lỗi này đã làm với bar
được undefined
. Khi không đọc kỹ, lỗi này khiến người mới bắt đầu nhầm lẫn đi sâu vào chi tiết của bar
phương pháp trênFoo
, hoàn toàn thiếu một phần lỗi cho thấy đối tượng thuộc lớp sai (trong trường hợp này là: không). Đó là một lỗi dễ dàng tránh được bằng cách đọc toàn bộ thông báo lỗi.
Tóm lược:
Luôn đọc kỹ toàn bộ thông báo lỗi trước khi bắt đầu gỡ lỗi. Điều đó có nghĩa là: Luôn kiểm tra loại lớp của một đối tượng trong thông báo lỗi trước , sau đó là các phương thức của nó , trước khi bạn bắt đầu điều tra vào bất kỳ stacktrace hoặc dòng mã nào mà bạn nghĩ rằng lỗi có thể xảy ra. 5 giây đó có thể giúp bạn tiết kiệm 5 giờ thất vọng.
tl; dr: Đừng nheo mắt khi in nhật ký: thay thế ngoại lệ hoặc sử dụng trình gỡ lỗi irb. Tránh lỗ thỏ bằng cách đọc lỗi cẩn thận trước khi gỡ lỗi.
In ra các biến bất cứ khi nào có thể. (Điều này được gọi là gỡ lỗi printf) Bạn có thể làm điều này bằng cách chạy
STDERR.puts x.inspect
hoặc là
STDERR.puts "Variable x is #{x.inspect}"
Nếu bạn muốn làm điều này dễ dàng hơn để gõ, thì bạn có thể muốn sử dụng đá quý mẫu mực .
Bật cảnh báo. Nếu bạn đang chạy ruby
thì hãy chạy nó bằng công -w
tắc (ví dụ ruby -w script.rb
). Nếu bạn đang chạy nó từ irb và bạn đang sử dụng phiên bản ruby trước 1.9.2, hãy nhập $VERBOSE = true
vào đầu phiên của bạn. Nếu bạn viết sai một biến đối tượng, một khi cảnh báo được bật, bạn sẽ nhận được
cảnh báo: biến
@valeus
thể hiện không được khởi tạo
Hiểu khái niệm về một nhị phân (trích dẫn sau đây là từ Thực tiễn của Nhà phát triển Agile )
Chia không gian vấn đề thành một nửa và xem một nửa có chứa vấn đề. Sau đó chia nửa đó một lần nữa và lặp lại.
Nếu bạn thành công với một nhị phân, bạn có thể thấy rằng có một dòng duy nhất không làm những gì bạn mong đợi. Ví dụ
[1, 2, 3].include?([1,2])
đưa ra một giá trị false
, mặc dù bạn nghĩ rằng nó sẽ trở lại true
. Trong trường hợp đó, bạn có thể muốn xem tài liệu. Các trang web cho tài liệu bao gồm ruby-doc.org hoặc APIdock . Trong trường hợp sau, bạn sẽ gõ include?
bên cạnh kính lúp gần góc trên cùng bên phải, chọn include?
cái có Array
bên dưới nó (nếu bạn không biết lớp nào [1, 2, 3]
, hãy nhập [1, 2, 3].class
irb) và bạn có bao gồm không? (Mảng) , mô tả những gì nó làm.
Tuy nhiên, nếu tài liệu không có ích, bạn có nhiều khả năng nhận được câu trả lời tốt nếu bạn có thể đặt câu hỏi về cách một dòng cụ thể không làm những gì cần làm, thay vì tại sao toàn bộ tập lệnh không làm gì nó nên
xóa tất cả mọi thứ
Chào mừng đến năm 2017 ^ _ ^
Được rồi, vì vậy nếu bạn không phản đối việc dùng thử IDE mới, bạn có thể làm miễn phí những điều sau đây .
launch.json
để sử dụng "cwd"
và và "program"
các lĩnh vực sử dụng{workspaceRoot}
vĩ mô"showDebuggerOutput"
và đặt nó thànhtrue
"debug.allowBreakpointsEverywhere": true
vscode
; Điều này không giống với Visual Studio . Đó là miễn phí, trọng lượng nhẹ, và thường được xem xét tích cực.View->Extensions
.vscode
và trong đó chúng tôi sẽ có một tệp được gọi làlaunch.json
nơi chúng tôi sẽ lưu trữ một số tùy chọn cấu hình.
launch.json
nội dung
{
"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
(hoặc Ctrl,) và cuộn cho đến khi bạn đạt đến Debug
phần. Mở rộng nó và tìm một trường có tên "debug.allowBreakpointsEverywhere"
- chọn trường đó và nhấp vào biểu tượng trông giống bút chì và đặt nó vào true
.Sau khi thực hiện tất cả những thứ thú vị đó, bạn sẽ có thể đặt các điểm dừng và gỡ lỗi trong một menu tương tự như vào giữa năm 2017 và một chủ đề tối hơn: với tất cả các nội dung thú vị như ngăn xếp cuộc gọi, trình xem biến, v.v.
PITA lớn nhất là 1) cài đặt các yêu cầu trước và 2) Ghi nhớ để định cấu hình .vscode\launch.json
tệp. Chỉ số 2 mới nên thêm bất kỳ hành lý nào vào các dự án trong tương lai và bạn chỉ có thể sao chép một cấu hình đủ chung chung như cấu hình được liệt kê ở trên. Có lẽ có một vị trí cấu hình chung hơn, nhưng tôi không biết trên đỉnh đầu của mình.
Tôi thực sự khuyên bạn nên video này, để chọn công cụ thích hợp tại thời điểm này để gỡ lỗi mã của chúng tôi.
https://www.youtube.com/watch?v=GwgF8GcynV0
Cá nhân, tôi nhấn mạnh hai chủ đề lớn trong video này.
Đó là hai xu của tôi!
Tất cả các câu trả lời khác đã đưa ra hầu hết mọi thứ ... Chỉ cần thêm một chút.
Nếu bạn muốn một số trình gỡ lỗi giống IDE hơn (không phải CLI) và không sợ sử dụng Vim làm trình chỉnh sửa, tôi khuyên bạn nên sử dụng plugin Vim Ruby Debugger cho nó.
Tài liệu của nó khá đơn giản, vì vậy hãy theo liên kết và xem. Nói tóm lại, nó cho phép bạn đặt điểm dừng ở dòng hiện tại trong trình chỉnh sửa, xem các biến cục bộ trong cửa sổ tiện lợi khi tạm dừng, chuyển qua / vào - gần như tất cả các tính năng gỡ lỗi thông thường.
Đối với tôi, thật thú vị khi sử dụng trình gỡ lỗi vim này để gỡ lỗi một ứng dụng Rails, mặc dù khả năng logger phong phú của Rails gần như loại bỏ sự cần thiết của nó.
Tôi mới phát hiện ra viên ngọc này (biến Pry thành trình gỡ lỗi cho MRI Ruby 2.0+)
https://github.com/deivid-rodriguez/pry-byebug
Cài đặt với:
gem install pry-byebug
sau đó sử dụng chính xác like pry
, đánh dấu dòng bạn muốn ngắt tại:
require 'pry'; binding.pry
Không giống như vani nâng lên tuy nhiên, đá quý này có một số GDB như chuyển hướng các lệnh quan trọng như next
, step
và 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
cờ (cảnh báo)irb
là một nơi khởi đầu tuyệt vời. Hãy thử sử dụng irb với khối nhỏ nghi vấn. Tôi yêu ruby-debug (ruby-debug19 cho Ruby 1.9+) vì nó giúp dễ dàng dừng chương trình đang chạy, kiểm tra các biến, thả vào irb, sau đó tiếp tục chạy.
Để dễ dàng gỡ lỗi tập lệnh shell Ruby, chỉ cần thay đổi dòng đầu tiên từ:
#!/usr/bin/env ruby
đến:
#!/usr/bin/env ruby -rdebug
Sau đó, mỗi khi bảng điều khiển trình gỡ lỗi được hiển thị, bạn có thể chọn:
c
cho Tiếp tục (đến Ngoại lệ tiếp theo, điểm dừng hoặc dòng với debugger
:),n
cho dòng tiếp theo,w
/ where
để hiển thị khung / ngăn xếp cuộc gọi,l
để hiển thị mã hiện tại,cat
để hiển thị các điểm bắt.h
để được trợ giúp thêm.Xem thêm: Gỡ lỗi với ruby-debug , Phím tắt cho đá quý ruby-debug .
Trong trường hợp tập lệnh chỉ bị treo và bạn cần quay lại, hãy thử sử dụng lldb
/ gdb
like:
echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -nf ruby)
và sau đó kiểm tra quá trình của bạn.
Thay thế lldb
bằng gdb
nếu hoạt động tốt hơn. Tiền tố sudo
để gỡ lỗi quá trình không sở hữu.
Kể từ Ruby 2.4.0, việc bắt đầu phiên IRB REPL ở giữa bất kỳ chương trình Ruby nào cũng dễ dàng hơn. Đặt các dòng này tại điểm trong chương trình mà bạn muốn gỡ lỗi:
require 'irb'
binding.irb
Bạn có thể chạy mã Ruby và in ra các biến cục bộ. Nhập Ctrl + D hoặc quit
để kết thúc REPL và để chương trình Ruby tiếp tục chạy.
Bạn cũng có thể sử dụng puts
và p
in ra các giá trị từ chương trình của mình khi chương trình đang chạy.
Nếu bạn đang sử dụng RubyMine , việc gỡ lỗi các tập lệnh ruby rất đơn giản và dễ hiểu.
Giả sử bạn có tập lệnh Ruby hello_world.rb
Đặt điểm dừng ở dòng 6 như bên dưới.
Bây giờ bạn có thể bắt đầu trình gỡ lỗi để chạy tập lệnh:
Sau đó, khi thực thi đạt đến điểm dừng, bạn sẽ có thể kiểm tra các biến, v.v.
gỡ lỗi printf
Luôn luôn có một cuộc tranh cãi xung quanh các kỹ thuật sửa lỗi, một số người thích gỡ lỗi bằng các câu lệnh in, một số khác thích đào sâu với trình gỡ lỗi.
Tôi khuyên bạn nên thử cả hai cách tiếp cận.
Trên thực tế, một trong những người đàn ông Unix cũ gần đây đã nói rằng, gỡ lỗi printf là một cách nhanh hơn để đi với anh ta ở một số điểm.
Nhưng nếu bạn là người mới trong một số công việc và cần phải hiểu một loạt mã lớn, thì thực sự rất hữu ích khi bước qua đó, đặt một số điểm dừng ở đây và ở đó, cùng với cách nó hoạt động.
Nó sẽ cung cấp cho bạn một số hiểu biết làm thế nào mã được dệt.
Nếu bạn chưa quen với một số phần mềm người khác, nó có thể giúp bạn bước qua đó.
Bạn sẽ nhanh chóng tìm ra nếu họ sắp xếp nó một cách thông minh, hoặc nếu đó chỉ là một đống cứt.
Chà, lib tiêu chuẩn ruby có trình gỡ lỗi giao diện điều khiển giống như gdb dễ sử dụng: http://ruby-doc.org/stdlib-2.1.0/libdoc/debug/rdoc/DEBUGGER__.html Không cần cài đặt thêm bất kỳ viên ngọc nào. Kịch bản Rails cũng có thể được gỡ lỗi theo cách đó.
ví dụ
def say(word)
require 'debug'
puts word
end
Mẹ của tất cả các trình sửa lỗi là màn hình in cũ đơn giản. Hầu hết thời gian, có lẽ bạn chỉ muốn kiểm tra một số đối tượng đơn giản, một cách nhanh chóng và dễ dàng là như thế này:
@result = fetch_result
p "--------------------------"
p @result
Điều này sẽ in ra nội dung của @result thành STDOUT với một dòng ở phía trước để dễ nhận biết.
Phần thưởng nếu bạn sử dụng khung có khả năng tự động tải / tải lại như Rails, bạn thậm chí sẽ không cần phải khởi động lại ứng dụng của mình. (Trừ khi mã bạn đang gỡ lỗi không được tải lại do cài đặt cụ thể của khung)
Tôi thấy điều này hoạt động cho 90% trường hợp sử dụng cho tôi. Bạn cũng có thể sử dụng ruby-debug, nhưng tôi thấy nó quá mức cần thiết.
Có nhiều trình gỡ lỗi với các tính năng khác nhau, dựa trên đó bạn đưa ra lựa chọn. Ưu tiên của tôi đã được thỏa mãn với động tác pry đó là: