2016-04-28 93 views
19

在为browser帮助文件中,有两个似乎非常类似的选项:浏览器中完成和继续有什么区别?

f

电流环路的执行完成或功能

c

退出浏览器并继续执行下一条语句。

他们之间有什么区别,在什么情况下差异明显?

什么可能是差一些线索 - 我写了一个与以下内容称为browse.R脚本:

for (i in 1:2){ 
    browser() 
    print(i) 
} 

这是使用c VS f结果:

> source("browse.R") 
Called from: eval(expr, envir, enclos) 
Browse[1]> c 
[1] 1 
Called from: eval(expr, envir, enclos) 
Browse[1]> c 
[1] 2 
> source("browse.R") 
Called from: eval(expr, envir, enclos) 
Browse[1]> f 
[1] 1 
Browse[2]> f 
[1] 2 

注意Browse[n]的等级发生变化。这仍然没有强调它们之间的任何实际区别。

我也想看看是否也许事情会从浏览器环境消失:

for (i in 1:2){ 
    a <- "not modified" 
    browser() 
    print(a) 
} 

Called from: top level 
Browse[1]> a <- "modified" 
Browse[1]> f 
[1] "modified" 
Browse[1]> a 
[1] "not modified" 
Browse[1]> a <- "modified" 
Browse[1]> c 
[1] "modified" 

所以没有区别有两种。

+0

的C内部和'这里F'大约一半, :https://github.com/wch/r-source/blob/e5b21d0397c607883ff25cca379687b86933d730/src/main/main.c [Ctrl + F为'ParseBrowser(SEXP CExpr,SEXP rho)'],但我的c不够强了解代码执行的不同当然 – Chris

+0

它可能是一个错误?预期的'f'行为是你完成当前函数,然后返回到浏览器(不退出)。当您查看源代码时,也会出现这种差异(请参阅上面的注释)。当输入'c'时,结果是'SET_RDEBUG(rho,0);'其中rho是指向调用浏览器的函数的指针。然而,当你看看'f'部分时,它将调试状态设置为true:'SET_RDEBUG(rho,1);'但是只有在退出函数(指针消失)之后,它应该将rho的调试状态设置为高一级在堆栈轨迹上。只是一个想法,不知道是否正确。 – takje

+0

@takje在这种情况下,浏览器不会更高,会吗?它会爆发并重新开始。 –

回答

0

您可以将finish作为break以其他语言。会发生什么情况是因为某些条件,例如找到可能导致错误的特定项目或项目,您不再在意迭代中的其他项目。另一方面,在另一方面,将停止在循环的当前行,忽略代码块的其余部分,并且继续到迭代中的下一个项目。如果您打算遍历迭代中的每个项目,并且忽略满足条件跳过的项目,则可以使用此选项。

+1

这就是描述听起来像,但它似乎并没有这样执行。你有没有一个例子,其中的两个行为不同? – Chris

+0

也许你可以给我一段代码,我会解释结果 –

+0

考虑'for(i in 1:2){browser(); print(i)}'。 'c'和'f'都会导致两者都被打印。 –

9

有一个小的差异。

  • c立即退出浏览器(和调试模式),然后以正常方式执行其余代码。
  • f在执行函数/循环的其余部分时停留在浏览器(和调试模式)中。在函数/循环完成后,他也返回到正常执行模式。

来源:R-source(行1105至1117年)和R-help

这有几个含义:

  • c关闭浏览器。这意味着从一个函数调用新的浏览器调用。因此您会看到该行:Called from: function()。另一方面,f不会关闭浏览器,因此您不会看到这一行。此行为的源代码位于:https://github.com/wch/r-source/...
  • 由于f停留在浏览器中,f还跟踪contextlevel的:

浏览器提示的形式浏览的[N]>:其中var {N}表示 '浏览器级别' 。浏览器可以在浏览时调用(并且通常在调试正在使用时),并且每次递归调用都会增加该数量。 (实际数量是上下文堆栈上“上下文”的数量:这通常是2用于浏览的外水平和1检查在调试器转储时)

这些差异可以用代码进行测试:

> test <- function(){ 
     browser() 
     browser() 
    } 

> test() 
Called from: test() 
Browse[1]> c 
Called from: test() 
Browse[1]> c 

> test() 
Called from: test() 
Browse[1]> f 
Browse[2]> f 

就我所见,两者之间没有实际的区别,除非在上下文堆栈中存在实际的目的。调试模式没有附加值。当你输入函数时,调试标志只会打开浏览器,但由于你已经在函数中,它不会触发另一个效果。

+0

可惜他们之间没有区别,但我想事情就是这样。 –

3

浏览器,并

至少对我来说,我觉得答案可以作为表映射出来,但是,让我们先架起浏览器(的使用),之间的差异对于那些谁可能还没有遇到它。

browser函数是大多数R调试技术的基础。本质上,调用browser暂停执行,并启动一个特殊的交互式会话,您可以在其中检查计算的当前状态,并逐步执行代码1命令。

一旦进入浏览器,您可以执行任何R命令。例如,可以使用ls()来查看本地环境。或者选择设置新变量,或者只需使用标准方法将值分配给变量即可更改分配给变量的值。浏览器还能理解一小组指令 。这使我们的讨论上完成继续 ...

在关系微妙到完成继续是:

  • 完成,或˚F :完成当前循环或函数的执行。
  • 继续,c:留下交互式调试并继续执行该功能的常规 。如果您修复了错误的 状态并想检查该功能是否正确继续,那么这很有用。

从本质上讲,我们谈论模式中的微妙之处。

enter image description here

浏览器/恢复概述

至少对我来说,你在调试用R.程序的情况下查看该具体如何可能会把完成继续。我相信很多人都明白这一点,但我包括了完整性,因为我个人真的很久没有。

  • browser让你看看哪个浏览器调用被放置在该函数的对象。
  • recover允许您查看这些对象以及该函数的调用者和所有其他活动函数中的对象。

自由使用browserrecovercat而你正在编写功能print让你的期望和R的期望收敛。

这样做的一个非常方便的方法是跟踪。例如,如果在 浏览myFun功能到底是方便,那么你可以做:

trace(myFun, exit=quote(browser()))

您可以自定义跟踪用以下命令:

trace(myFun, edit=TRUE)

如果遇到错误,则调试是适当的行动。有至少两种调试方法在 。第一种方法是看看发生错误的点的状态 。通过设置错误 选项为此做好准备。这两个最有可能的选择是:

options(error=recover)

options(error=dump.frames)

不同的是,与recover则会自动扔到调试 模式,但与dump.frames你馅饼调试通过执行:

debugger()

在任一情况下,你都带有一个选择画面(环境)的 的活性功能检查。

您可以强制R键警告视为与指挥失误:

options(warn=2)

如果你想在错误选项在.First功能设置,那么你需要一个 伎俩,因为当执行.First时,并非一切都已到位:

options(error=expression(recover()))

options(error=expression(dump.frames()))

用于调试第二个想法是到步骤通过函数在执行时。如果 要步功能myfun,然后执行:

debug(myfun)

,然后执行涉及myfun的声明。当您完成调试, 做:

undebug(myfun)

一个更复杂的版本,这种调试可在 调试包中找到。

参考文献:

+0

这是一个非常好的调试总览,但我不认为它回答我的具体问题 –

+0

@ sebastian-c - 感谢您的反馈。我更新了答案(希望)解决您的具体问题。我不得不承认,我更喜欢takje的回答(upvoted)。我想离开,但我认为它可能有助于提供更完整的使用和继续的背景。希望有用。保重。 – Technophobe01

+0

你的编辑更加具体,并且仍然是一个很好的调试概述,并且确实讨论了c和f,但不幸的是并没有描述差别明显的情况。 –

相关问题