2016-05-24 4 views
10

Wie kann ich effizient in R debuggen, wenn Pakete wegen der faulen Auswertung unbekannt sind. Ich möchte die grundlegende browser() Funktionalität behalten, wie es gut funktioniert - sogar mit der testthat package. Wie im Folgenden erläutert, ist post, --with-keep.source für mein Projekt in "Projektoptionen => Build Tools" festgelegt.Debugging-Paket :: function() obwohl Lazy-Auswertung verwendet wird

das Verhalten zu reproduzieren, ein Paket erstellen TestDebug

myfun <- function(a,b) {return(a+b)} 

und ein Skript enthält example.R

{ 
browser() 
TestDebug::myfun(1,2) 
} 

bearbeiten: werden ebenfalls abgedeckt Die Situation, in TestDebug::myfun(1,2) Anrufe otherpackage::myfun2(1,2) sollte. Ich denke, die Situation sollte in jedem "echten" Paket auftreten?

Antwort

5

Folgendes funktioniert für mich.

Ich habe mein Paket TestDebug mit meiner Funktion

myfun <- function(a,b) {return(a+b)}

Wenn ich das Skript

debug(TestDebug::myfun) 
TestDebug::myfun(1,2) 

der Debugger direkt in die Quelle der TestDebug::myfun() nicht in die :: Funktion, wie es funktioniert wenn Sie eine browser() vor dem Anruf an TestDebug::myfun(1,2) platzieren.

Wie Sie in Ihrer Frage erwähnen: in realen Situationen ruft TestDebug::myfun(1,2) oft otherpackage::myfun2(1,2). Wenn Sie versuchen, in otherpackage::myfun2(1,2) zu treten, landen Sie innerhalb der :: Funktion wieder.

Um dies zu verhindern ich diese Funktionen in anderen Funktionen dem debug Index on the fly genannt hinzu:

Sobald Sie befinden sich auf der Linie innerhalb TestDebug::myfun() wo otherpackage::myfun2(1,2) I laufen debug(otherpackage::myfun2(1,2)) in der Konsole genannt. Danach kann ich ohne Probleme in otherpackage::myfun2(1,2) treten und im Quellcode otherpackage::myfun2(1,2) enden. (..und nicht im Quellcode von ::)

Vergessen Sie nicht undebug(otherpackage::myfun2(1,2)) anrufen, nachdem Sie sicher sind, dass Ihr Problem ist nicht in otherpackage::myfun2(1,2) die Debugger zu verhindern, in otherpackage::myfun2(1,2) das nächste Mal springen sie aufgerufen wird.

Wenn Sie möchten, können Sie auch debugonce(otherpackage::myfun(1,2)) (anstelle von debug(..)) verwenden, um nur einmal eine Funktion zu debuggen.

+0

Das löst das Problem für mein Beispiel. Ich erkannte, dass, wenn Sie ein "echtes" Paket mit mehr Ebenen, z. 'TestDebug :: myfun (1,2)' ruft 'otherpackage :: myfun2 (1,2)' auf, das gleiche Problem tritt erneut auf. Siehe meine Bearbeitung der Frage. – Christoph

+0

Ihre verbesserte Antwort ist mindestens eine Problemumgehung. Ich frage mich immer noch, ob es keine weiteren Optionen gibt. Etwas wie eine Debug-Option 'skip_base_functions', die das gewünschte Verhalten haben könnte. – Christoph