3

thisおよびthisの別のフォローアップ。

実際の質問

質問1

何らかの条件 (asimpleErrorなど) が発生した場合、別の条件にならないものが見つかるまで、実際のハンドラー関数の範囲を体系的にテストするそれぞれの再起動ハンドラーを呼び出すにはどうすればよいですか? 使用可能な最後のハンドラーが試行された場合は、デフォルトの中止再開ハンドラーを呼び出す必要があります ( invokeRestart("abort"))。実装では、実際に使用する「ハンドラ スイート」を柔軟に指定できるようにする必要があります。

質問2

a)再起動ハンドラと一緒に指定されたテスト関数がどのように機能するか、およびb)それを使用するのが理にかなっている場所がわかりません。助言がありますか?短い例は素晴らしいでしょう!

のヘルプページにwithRestartsは次のように書かれています。

再開仕様の最も柔軟な形式は、ハンドラー、説明、およびテストを含むいくつかのフィールドを含めることができるリストです。テスト フィールドには、1 つの引数である条件の関数が含まれている必要があります。再起動が条件に適用される場合は TRUE を返し、適用されない場合は FALSE を返します。デフォルト関数は、すべての条件に対して TRUE を返します。


詳細が気になる方へ

以下に、質問 1 に関する私の最初のアプローチを示しますが、もっとクリーンで簡単な方法があると確信しています ;-)

foo <- function(x, y) x + y
fooHandled <- function(
    x,
    y,
    warning=function(cond, ...) {
        invokeRestart("warninghandler", cond=cond, ...)},
    error=function(
        cond, 
        handlers=list(
            expr=expression(x+"b"),
            expr=expression(x+"c"),
            expr=expression(x+100)
        ),
        ...) {
            invokeRestart("errorhandler", cond=cond, handlers=handlers, ...)
        }
) {
    expr <- expression(foo(x=x, y=y))
    withRestarts(
        withCallingHandlers(
            expr=eval(expr),
            warning=warning,
            error=error 
        ),
        warninghandler=function(cond, ...) warning(cond),
        errorhandler=function(cond, handlers, ...) {
            idx <- 1
            do.continue <- TRUE
            while (do.continue) {
                message(paste("handler:", idx))
                expr    <- handlers[[idx]]                            
                out     <- withRestarts(
                    tryCatch(
                        expr=eval(expr),
                        error=function(cond, ...) {
                            print(cond)
                            message("trying next handler ...")
                            return(cond)
                        }
                    )
                )
                idx <- idx + 1
                do.continue <- inherits(out, "simpleError")
            }
            return(out)
        }
    )
}

> fooHandled(x=1, y=1)    
[1] 2
> fooHandled(x=1, y="a")
handler: 1
<simpleError in x + "b": non-numeric argument to binary operator>
trying next handler ...
handler: 2
<simpleError in x + "c": non-numeric argument to binary operator>
trying next handler ...
handler: 3
[1] 101

編集

tryCatchパーツをパーツに置き換える方法も聞きたいwithCallingHandlersです。withCallingHandlers()の値を決定するためにピックアップできるものは実際には何も返さないようですdo.continue

4

0 に答える 0