【问题标题】:Invoke browser in parent context在父上下文中调用浏览器
【发布时间】:2019-03-19 23:40:50
【问题描述】:

假设我有以下代码:

maybeBrowser <- function (msg) {
    if (interactive()) {
        cat(msg, "\n")
        ???
    } else {
        stop(msg)
    }
}

foo <- function (cond, ...) {
    if (cond) maybeBrowser("What a mess")
}

什么会???如果 cond 评估为 TRUE,则必须看起来像这样才能在 foo 的上下文中调用 browser()

【问题讨论】:

    标签: r


    【解决方案1】:

    也许不是最优雅的,但这似乎可以满足我的要求。

    首先,两个注意事项:

    1. 我正在添加browser(); 1,我知道它不会立即起作用。 ;1 是因为browser() 后面没有代码时会立即退出。如果if/else 块之后有什么东西,那么你可能不需要它,但它就在那里。 (这仅对 emacs/ESS 是必需的:https://github.com/emacs-ess/ESS/issues/178

    2. 我在foo 环境中添加了一个变量,以证明我们没有(然后看到)它。

    首先,失败的尝试:

    maybeBrowser <- function (msg) {
        if (interactive()) {
            cat(msg, "\n")
            browser()
            q
        } else {
            stop(msg)
        }
    }
    foo <- function (cond, ...) {
        cat(capture.output(environment()), "\n")
        in_foo <- 1
        if (cond) maybeBrowser("What a mess")
    }
    
    foo(TRUE)
    # <environment: 0x000000001b2beba0> 
    # What a mess 
    # Called from: maybeBrowser("What a mess")
    # Browse[1]> 
    debug at #5: q
    # Browse[2]> 
    environment()
    # <environment: 0x000000001b280030>  <---- this is different
    # Browse[2]> 
    ls()
    # [1] "msg"
    

    现在对代码进行调整,由 https://stackoverflow.com/a/23891089/3358272 推动

    maybeBrowser <- function (msg) {
        if (interactive()) {
            cat(msg, "\n")
            return(evalq(browser(skipCalls=1), envir=parent.frame()))
        } else {
            stop(msg)
        }
    }
    foo <- function (cond, ...) {
        cat(capture.output(environment()), "\n")
        in_foo <- 1
        if (cond) maybeBrowser("What a mess")
    }
    
    foo(TRUE)
    # <environment: 0x000000001b0b9d40> 
    # What a mess 
    # Called from: eval(quote({
    #     browser()
    #     1
    #   ...
    # Browse[1]> 
    debug at #4: [1] 1
    # Browse[3]> 
    environment()
    # <environment: 0x000000001b0b9d40>  <---- this is now the same
    # Browse[3]> 
    ls()
    # [1] "cond"   "in_foo"
    

    但是,这不允许您继续,单步执行foo 中的任何以下代码,因此这是一个不完整的答案。不幸的是,我认为这可能不可行......但也许更了解内部情况的 R bubba 会对此有更清楚的了解。

    【讨论】:

    • 这似乎可以解决问题:return(evalq(browser(skipCalls=1), envir=parent.frame()))
    • @user2554330 对quoteing 通话很好。然而,当我尝试这个(添加;1,为我的emacs/ess 的东西),虽然这第一次正常工作,第二次和随后的browse 退出而不是继续介入foo
    • 在上面的示例中,maybeBrowser 调用之后没有任何语句。当我添加一个时,在那里输入n(用于“下一步”)步骤。
    • 在我的测试中,我添加了更多命令。获取文件(定义函数)后,对foo(TRUE) 的第一次调用导致逐步执行以下命令,但对foo(TRUE) 的第二次和后续调用(不重新定义函数)不会逐步执行后续命令.这也可能是 emacs/ess 问题,尽管第一个 emacs/ess 问题是由于它将调用分配给trace 的位置,但这似乎不是同一件事。
    • 谢谢大家。 return(evalq(browser(skipCalls=1), envir=parent.frame())) 的解决方案非常适合我。
    猜你喜欢
    • 2018-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-27
    • 2019-07-19
    • 2014-10-27
    • 2011-02-02
    • 2011-01-12
    相关资源
    最近更新 更多