2012-10-29 35 views
22

Tôi quan sát thấy sự khác biệt giữa phiên R tương tác và không tương tác về traceback() mà tôi không hiểu. Đối với mã bên dưới, nó sẽ tạo ra lỗi, nhưng trong phiên R tương tác, tôi có thể xem thông tin truy nguyên, trong khi nếu tôi lưu mã vào test.R và gọi mã qua số Rscript test.R hoặc R -f test.R, tôi không còn có thể xem traceback:traceback() cho các phiên R tương tác và không tương tác

f = function() { 
    on.exit(traceback()) 
    1 + 'a' 
} 
f() 

Trong một phiên R tương tác: thực hiện

> f = function() { 
+ on.exit(traceback()) 
+ 1 + 'a' 
+ } 
> f() 
Error in 1 + "a" : non-numeric argument to binary operator 
1: f() 

không tương tác:

$ Rscript test.R 
Error in 1 + "a" : non-numeric argument to binary operator 
Calls: f 
No traceback available 
Execution halted 

tôi không thấy lời giải thích trong số ?traceback và tôi tự hỏi liệu có cách nào để bật truy xuất cho các phiên R không tương tác hay không. Cảm ơn!

+0

'traceback' tìm kiếm một đối tượng được gọi là '.Traceback' trong' baseenv() '. Nó trông (từ 'src/main/errors.c') như thế này chỉ được tạo nếu, trong số các điều kiện khác,' R_Interactive || hasHandler'. Không có '.Traceback', bạn sẽ nhận được thông báo" Không có traceback ". Ngoài ra còn có một cảnh báo dưới '? Traceback' đề cập đến' .Traceback'. – BenBarnes

+0

Nếu bạn chỉ thiết lập các tùy chọn (error = traceback) trong kịch bản và xóa cuộc gọi on.exit, bạn sẽ có hiệu ứng mong muốn. Mặc dù nó tạo ra trùng lặp vì "bước" của lỗi. –

+0

@BrandonBertelsen, Theo như tôi có thể nói, điều đó vẫn sẽ không cung cấp cho bạn quyền truy cập vào thông tin truy nguyên, mặc dù ngăn xếp cuộc gọi được trả lại trong trường hợp xảy ra lỗi trong phiên không tương tác. – BenBarnes

Trả lời

20

Với giá trị mặc định của đối số của nó, traceback() sẽ tìm kiếm một đối tượng có tên .Traceback trong baseenv() để biết thông tin về ngăn xếp cuộc gọi. Có vẻ như (từ src/main/errors.c) như .Traceback chỉ được tạo nếu, trong số các điều kiện khác, R_Interactive || haveHandler, gợi ý rằng đối tượng này không được tạo trong các phiên không tương tác. Nếu không có đối tượng nào có tên là .Traceback, bạn sẽ nhận được thông báo "Không có traceback".

Tuy nhiên, bằng cách chuyển giá trị không NULL đến đối số x của traceback(), người ta có thể lấy thông tin về ngăn xếp cuộc gọi từ phiên không tương tác. Với giá trị số nguyên khác 0 (cho biết số lượng cuộc gọi để bỏ qua trong ngăn xếp), chức năng cấp c (R_GetTraceback) được gọi để điều tra ngăn xếp cuộc gọi thay vì tìm trong .Traceback.

Vì vậy, có một vài cách để có được thông tin traceback trong một phiên không tương tác:

f = function() { 
    on.exit(traceback(1)) 
    1 + 'a' 
} 
f() 

Hoặc, thiết options như Brandon Bertelsen đề nghị

options(error=function()traceback(2)) 

Các giá trị khác nhau truyền cho x trong hai ví dụ cho số lượng chức năng khác nhau để bỏ qua

  1. Trong ví dụ on.exit, traceback(1) bỏ qua cuộc gọi đến traceback().

  2. Trong cài đặt mẫu options, có thêm một chức năng ẩn danh gọi là traceback() nên/cũng có thể bị bỏ qua.

Trong ví dụ trong OP, không có nhiều thông tin thu được bằng cách sử dụng traceback() so với traceback tự động cung cấp trong trường hợp có lỗi trong một phiên không tương tác. Tuy nhiên, với các hàm lấy (và được truyền) đối số, sử dụng traceback() sẽ có nhiều thông tin hơn so với bản trình bày tiêu chuẩn của ngăn xếp cuộc gọi trong phiên không tương tác.

+0

Cảm ơn rất nhiều! Tôi đã không nhận ra rằng thiết lập 'x' cho một số cũng hoạt động cho các phiên R không tương tác. –

+4

Lưu ý rằng bằng cách sử dụng 'tùy chọn (lỗi = hàm() traceback (2))' sẽ gây ra các kịch bản để thoát khỏi thành công ngay cả khi một lỗi xảy ra! Một giải pháp là sử dụng 'error = function() {traceback (2); if (! interactive()) quit ("no", status = 1, runLast = FALSE)} 'thay vào đó (các đối số dừng được sử dụng ở đây là từ [hành vi lỗi mặc định] (https://stat.ethz.ch/R -manual/R-devel/library/base/html/stop.html)). – dshepherd

2

Ngoài ra còn có khả năng đổ thông tin gỡ lỗi và tải chúng sau này.(Xem tốt ?debugger trang trợ giúp và ý kiến ​​về chủ đề này)

qua ví dụ:

options(error = quote(dump.frames("testdump", TRUE))) 

...

load("testdump.rda") 
debugger(testdump) 

hoặc

options(error = quote({dump.frames(to.file = TRUE); q(status = 1)})) 
Các vấn đề liên quan