2012-12-06 32 views
4

我希望有一个R函数,它允许我模拟R控制台,不同之处在于表达式在与全局环境不同的环境中进行评估。 (我想在R中使用它作为替代调试方法,它允许恢复调用函数的本地参数,然后通过将功能代码逐步粘贴到仿真R控制台中进行调试)。下面是一个使用解析和eval和做这项工作中途功能(模拟的控制台按下Esc键时停止):在R /仿真R控制台中解析多行表达式

my.console = function() { 
    while(TRUE) { 
    tryCatch({ 
     expr.out <- capture.output(eval(parse(prompt=": "))) 
     if (length(expr.out)>0) { 
     cat(expr.out,"\n") 
     } 
    }, error = function(e) { 
     str = as.character(e) 
     message(str) 
    }) 
    } 
} 

console.env = new.env(parent=globalenv()) 
console.env$hello = "Hello World" 
environment(my.console) <- console.env 

my.console() 

一个然后可以在模拟控制台,例如计算简单表达式

: 5*5 
[1] 25 
: hello 
[1] "Hello World" 

问题是我无法解析多行代码,当从我的脚本粘贴if语句的开始时,会抛出错误。

: if (TRUE) { 
Error in parse(prompt = ": "): 2:0: unexpected end of input 

R控制台意识到更多代码将在下一行中执行并将提示更改为+。我想知道是否也有类似行为的解析函数的变体。 到目前为止,我唯一的想法是在错误消息中搜索子串“意外的输入结束”,以及是否发现它继续解析。但例如因为一些R错误消息似乎取决于R运行的语言,所以我对这种方法并不满意。有没有人知道我该如何编写一个更好的仿真R控制台来解析多行R代码?

回答

0

如果要交互式地逐步执行代码,可以使用内置函数browser()和命令n,请参阅?browser。使用示例:

f <- function(x) { 
    # invoke interactive debugging 
    browser() 

    # rest of the function - by pressing 'n' while in browser mode, the expressions 
    # will be executed one after another and you are able to explore the 
    # intermediate values of variables etc. (as in standard R promt) 
    y <- x^2 
    [...] 
} 

如果这个不适合你的需求,你可能有一个看的browser的源代码。

+0

感谢您的建议,但我的目标是为调试提供一种替代方法,我在CRAN包restorepoint实现。封装小插曲详细描述了它,为什么我更喜欢它通过browser()设置的断点。到目前为止,该软件包似乎与我的肮脏的解决方法一起工作......但如果在R中有一种更简洁的方式来模拟解析多行表达式的自定义控制台,那将会很不错。 –

1

为什么不试试你的分离编码输入和parse命令,例如,

s <- scan(what="list", multi.line=TRUE) 
for(i in 1:length(s)){ 
    capture.output(eval(parse(text=s)[i])) 
    # etc... 
} 
+0

感谢您的建议,但像在R控制台中一样,我希望一旦输入完整的R表达式,就应立即进行评估。为了使扫描停止,似乎必须明确地输入空行。此外,似乎并不直接评估多行表达式,我得到一个错误。到目前为止,我宁愿留在我上面描述的检查R eror消息的肮脏的方法。 –

+0

您是否需要输入任意数量的行? 'scan'接受'nlines'参数,这样就不必输入空行来停止扫描。 – Thomas

+0

设置nlines = 1可能会有所帮助,但仍然会有问题来检测第一行是否是多行表达式的开始并正确解析整个表达式 –