2

どのようmuffleWarninginvokeRestart("muffleWarning")実装されていますか?次のコードでは、次のように尋ねます。

e <-expression({
  warning("Step 1",immediate.=TRUE)
  warning("Step 2",immediate.=TRUE)
})

r <- withRestarts(withCallingHandlers(eval(e)
                                      ,warning=function(co){
                                        print(co) #1
                                        invokeRestart("mymuffleWarn",co)
                                      })
                  , mymuffleWarn=function(co) print(conditionMessage(co)))

最初の警告の出力 (#1 から) を取得します。ただし、 (で)に置き換えるmymufflewarnと、すべての出力が表示されます。muffleWarninginvokeRestartprint(co)

ありがとう

4

1 に答える 1

0

R ソース コードを grep すると、次のことがわかります。

.signalSimpleWarning <- function(msg, call)
    withRestarts({
           .Internal(.signalCondition(simpleWarning(msg, call), msg, call))
           .Internal(.dfltWarn(msg, call))
        }, muffleWarning = function() NULL)

から呼び出される

static void vsignalWarning(SEXP call, const char *format, va_list ap)
{
    char buf[BUFSIZE];
    SEXP hooksym, hcall, qcall;

    hooksym = install(".signalSimpleWarning");
    if (SYMVALUE(hooksym) != R_UnboundValue &&
        SYMVALUE(R_QuoteSymbol) != R_UnboundValue) {
        PROTECT(qcall = LCONS(R_QuoteSymbol, LCONS(call, R_NilValue)));
        PROTECT(hcall = LCONS(qcall, R_NilValue));
        Rvsnprintf(buf, BUFSIZE - 1, format, ap);
        hcall = LCONS(mkString(buf), hcall);
        PROTECT(hcall = LCONS(hooksym, hcall));
        eval(hcall, R_GlobalEnv);
        UNPROTECT(3);
    }
    else vwarningcall_dflt(call, format, ap);
}

から呼び出されます

void warningcall(SEXP call, const char *format, ...)
{
    va_list(ap);
    va_start(ap, format);
    vsignalWarning(call, format, ap);
    va_end(ap);
}

その関数は、C コードで警告を生成するために使用され、またdo_warning、backs を実行する C 関数から呼び出されwarning()ます。

そのためmuffleWarning、警告が発生したときはいつでもハンドラーを使用できます。

于 2013-10-28T15:48:49.707 に答える