2011-08-05 10 views
11

私は私のシナリオは私が書いてきたすべてが他の関数への呼び出しを行う機能を有していることであるR.でisdebugged()にグローバル対応を見つけようとしています、と私は回していますdebug()は、デバッグ中にさまざまな機能をオン/オフします。しかし、どの機能がデバッグされるように設定されているかはわかりません。私がループを忘れて始めると、もっと多くの出力(厄介ではないがひどい)が得られるかもしれません。リスト機能はRに設定

私の現在のアプローチは、以下のような関数を使用することです。listDebugged(ls())で呼び出すか、読み込まれたライブラリの項目をリストすることができます(下記の例を参照)。これで十分ですが、ワークスペースまたはロードされているパッケージのすべての関数のリストで呼び出す必要があります。私はこれらを取得する別の関数をラップすることができます。デバッグ機能を直接質問する簡単な方法や、デバッグフラグが設定された関数のリストを隠している環境の不明瞭な部分を照会する方法があるようです。だから、

、2つのパートの質問:

  1. は、デバッグフラグを設定して機能を照会するために存在する単純な呼び出しはありますか?
  2. もしそうでなければ、私が見落としてきた細かいことはありますか?たとえば、あるパッケージのある関数が別のパッケージをマスクすると、誤解を招く結果が返ってくる可能性があります。

私は試みることができる、それはまた、デバッグ関数名の隠されたリストを維持する関数内debugundebugをラップすることです別の方法があることを認識しています。私はまだそれが安全なことだとは確信していません。

UPDATE(8/5/11):私はSO検索、およびそれ以前の質問を見つけることができませんでした。しかし、SOの "関連する質問"リストには、an earlier question that is similarが表示されていますが、その質問に対する回答の機能は@cbeleitesが提供する機能よりも冗長で低速です。私がしていた間、古い質問はまたコードを提供しません。 :)

コード:

listDebugged <- function(items){ 
    isFunction <- vector(length = length(items)) 
    isDebugged <- vector(length = length(items)) 

    for(ix in seq_along(items)){ 
     isFunction[ix] <- is.function(eval(parse(text = items[ix]))) 
    } 

    for(ix in which(isFunction == 1)){ 
     isDebugged[ix] <- isdebugged(eval(parse(text = items[ix]))) 
    } 
    names(isDebugged) <- items 
    return(isDebugged) 
} 

# Example usage 
listDebugged(ls()) 
library(MASS) 
debug(write.matrix) 
listDebugged(ls("package:MASS")) 
+0

Rベースでは、 'debug'関数をラップする以外の方法はありません。 – kohske

答えて

6

はここlistDebugged機能で私のスローです:

ls.deb <- function(items = search()){ 
    .ls.deb <- function (i){ 
    f <- ls (i) 
    f <- mget (f, as.environment (i), mode = "function", 

       ## return a function that is not debugged 
       ifnotfound = list (function (x) function() NULL) 
       ) 

    if (length (f) == 0) 
     return (NULL) 

    f <- f [sapply (f, isdebugged)] 
    f <- names (f) 

    ## now check whether the debugged function is masked by a not debugged one 
    masked <- !sapply (f, function (f) isdebugged (get (f))) 

    ## generate pretty output format: 
    ## "package::function" and "(package::function)" for masked debugged functions 
    if (length (f) > 0) { 
     if (grepl ('^package:', i)) { 
     i <- gsub ('^package:', '', i) 
     f <- paste (i, f, sep = "::") 
     } 

     f [masked] <- paste ("(", f [masked], ")", sep = "") 

     f 
    } else { 
     NULL 
    } 
    } 


    functions <- lapply (items, .ls.deb) 
    unlist (functions) 
} 
  • 出力フォーマットは、そうでない場合にのみデバッグ機能(あるとして、私は、別の名前を選びました私は簡単に出力形式package::function(というかnamespace::functionを持って
  • )機能の何千ものを得るが、パッケージは、nを持っていますamespacesはすぐにとにかく)。デバッグ機能がマスクされている場合は
  • は、出力はデフォルトでは元の質問ので、全体の検索パス
+0

+1これはいいですし、うまくいくようです。私は今それを踏んで、 'f 'で何をしているのかを学んでいます。賢い – Iterator

+0

自分の見落とし: 'debug()'をステップ実行することは、それが何をしているのかを知る良い方法です。まだ 'debug'をうまく使います。 :) – Iterator

+0

ありがとう!私はこの機能からいくつかの新しい機能とアイデアを学びました。 – Iterator

2

throught探している"(package::function)"

  • ですが、私はMark Bravington's debug packageでより多く見てきました。そのパッケージを使用している場合、check.for.traces()は、mtraceでデバッグ中の機能をリストする適切なコマンドです。 1は、Rデバッガと様々なtraceオプションで多くの時間を費やしている場合

    デバッグパッケージは一見の価値があります。

  • 1

    @cbeleites私はあなたの答えが好きですが、それは私にとってはうまくいかなかったのです。私はこれが動作するようになったが、それはあまり機能しているよりも上のあなた(無再帰をチェックし、無かわいいプリント)

    require(plyr) 
    debug.ls <- function(items = search()){ 
        .debug.ls <- function(package){ 
        f <- ls(package) 
        active <- f[which(aaply(f, 1, function(x){ 
         tryCatch(isdebugged(x), error = function(e){FALSE}, finally=FALSE) 
         }))] 
        if(length(active)==0){ 
         return(NULL) 
        } 
        active 
        } 
    
        functions <- lapply (items, .debug.ls) 
        unlist (functions) 
    } 
    
    0

    私は常にあるため使用上の注意事項undebug機能に失敗するbrowser窓枠に巻き込まれる。だから私は2つの関数を作成し、私の.Rprofileに追加しました。ヘルパー関数はかなり簡単です。

    require(logging) 
    
    # Returns a vector of functions on which the debug flag is set 
    debuggedFuns <- function() { 
        envs <- search() 
        debug_vars <- sapply(envs, function(each_env) { 
        funs <- names(Filter(is.function, sapply(ls(each_env), get, each_env))) 
        debug_funs <- Filter(isdebugged, funs) 
        debug_funs 
        }) 
        return(as.vector(unlist(debug_vars))) 
    } 
    
    # Removes the debug flag from all the functions returned by `debuggedFuns` 
    unDebugAll <- function(verbose = TRUE) { 
        toUnDebug <- debuggedFuns() 
        if (length(toUnDebug) == 0) { 
        if (verbose) loginfo('no Functions to `undebug`') 
        return(invisible()) 
        } else { 
        if (verbose) loginfo('undebugging [%s]', paste0(toUnDebug, collapse = ', ')) 
        for (each_fn in toUnDebug) { 
         undebug(each_fn) 
        } 
        return(invisible()) 
        } 
    } 
    

    私はそれらをテストして、うまくいきます。お役に立てれば!

    2

    これはlsf.strを使用して、簡単なワンライナーです:

    which(sapply(lsf.str(), isdebugged)) 
    

    あなたはより多くの引数に?lsf.strを参照して、関数内の環境を変更することができます。

    +0

    これは、接続されているすべての関数をチェックする例です: '名前(sapply(unlist(lapply(search()、function(x)lsf.str(pos = x)))、isdebugged)))' ' – jbaums

    関連する問題