2016-08-25 13 views
1

on.exitを使用する関数の最後のステートメントの後にトレース式を挿入したいとします。簡素化されたバージョン(実際の機能は、パッケージのロックされた名前空間にある):`trace`最後のステートメントの後

f <- function() { 
    on.exit(NULL) 
    x <- 1 
    x <- 2 
} 

trace(f, at=4, quote(cat(x, "\n"))) 
f() 
## Tracing f() step 4 
## 1 
trace(f, at=5, quote(cat(x, "\n"))) 
## Error in fBody[[i]] : subscript out of bounds 

アイデアはtraceを使用して、画面に出編「2」catを取得することです。これを行う方法がないように見えます。私は間違っていると思っています。私はedit引数を使用することができます実現しており、この恐ろしいからくりを思い付いたヘルプページの必死の再読み込みで

答えて

1

さて、:

trace_editor <- function(name, file, title, ...) { 
    body(name) <- bquote(
    { 
     .res <- .(body(name)) 
     .doTrace(cat(x, "\n"), "at end") 
     .res 
    } 
) 
    name 
} 
old.edit <- options(editor=trace_editor) 
trace(f, edit=TRUE) 
options(old.edit) 
f() 
## Tracing f() at end 
## 2 
## [1] 2 

基本的に、私はラップするカスタムエディタ機能を作成します本体を計算する別の式の中にある既存の関数本体を呼び出し、traceコマンドを実行して値を返します。

これに関する1つの問題は、可視性を処理しないことです(末尾の[1] 2は表示しないでください)。

.res <- .(body(name)) 

.res <- withVisible(.(body(name))) 

し、必要に応じてinvisible(.res$value)を返すために最後にいくつかの処理を追加する:これは変えることによって対処することができます。これは残念なことに、withVisibleがコールスタックの一部になって以来、エラー報告の混乱を招いています。通常trace dの関数エラー報告はほとんど透過的に機能します。

1

trace()を使用することに自分自身を制限しない場合は、好きな場所にトレースステートメントを追加することは悪いことではありません。以下に定義されているtrace_last()は、関数本体の後にトレースを追加します。もともと、on.exit呼び出しの後にトレースを追加しようとしていたと思っていました。これはtrace_after()です。

f <- function() { 
    on.exit(message("exit")) 
    x <- 1 
    x <- 2 
} 

trace_last <- function(f, expr) { 
    body(f) <<- call("{", body(f), expr) 
} 

trace_after <- function(f, expr) { 
    body(f) <<- call("{", body(f), bquote(on.exit(.(expr), add = TRUE))) 
    f() 
} 

f() 
#> exit 
trace_last(f, quote(message(x))) 
f() 
#> 2 
#> exit 
trace_after(f, quote(message("after on exit"))) 
#> 2 
#> exit 
f() 
#> 2 
#> exit 
#> after on exit 
+0

私は(例えば ''、untrace' tracingState'、また半認可形でロックの名前空間内の関数を変更する)既存の機能を活用できるように 'trace'を使用しようとしています。 'call'の使い方がいいです、+1。 – BrodieG

+0

最後のポイント(名前空間がロックされている)をクリアするための変更された質問。行方不明から申し訳ありません。 – BrodieG

関連する問題