使用源代码与解析代码有什么注意事项。 EVAL?

时间:2014-06-27 14:40:25

标签: r eval

短版

我可以替换

source(filename, local = TRUE, encoding = 'UTF-8')

eval(parse(filename, encoding = 'UTF-8'))

没有任何破损的风险,使UTF-8源文件在Windows上运行?

长版

我目前正在通过

加载特定的源文件
source(filename, local = TRUE, encoding = 'UTF-8')

然而,众所周知this does not work on Windows,完全停止。

作为解决方法,Joe Cheng suggested使用

eval(parse(filename, encoding = 'UTF-8'))

这似乎工作得非常好 1 但即使在查阅了source的源代码之后,我也不明白它们在一个关键细节上的区别如何:

sourcesys.source 只需parse,然后eval文件内容。相反,他们解析文件内容,然后手动迭代解析表达式,然后逐个eval。我不明白为什么在sys.source中必须这样做(source至少使用它来显示详细的诊断,如果有这样的话;但是sys.sourcenothing of the kind):

for (i in seq_along(exprs)) eval(exprs[i], envir)

单独eval语句的目的是什么?为什么它直接在子表达式上迭代索引?还有什么其他警告?

澄清:我关注sourceparse的其他参数,其中一些可以通过选项设置。


1 source因编码而被parse绊倒的原因并不是source尝试转换输入的事实文本。 parse没有这样的东西,它按原样读取文件的字节内容,只是将其Encoding标记为内存中的UTF-8

1 个答案:

答案 0 :(得分:5)

这不是一个完整的答案,因为它主要解决问题的seq_along部分,但过于冗长而不能作为评论。

seq_along后跟[与仅使用for i in x方法之间的一个关键区别(我认为这与seq_along后面跟[[相似[)是前者保留表达式。这是一个说明差异的例子:

> txt <- "x <- 1 + 1
+ # abnormal expression
+   2 *
+     3
+ "
> x <- parse(text=txt, keep.source=TRUE)
> 
> for(i in x) print(i)
x <- 1 + 1
2 * 3
> for(i in seq_along(x)) print(x[i])
expression(x <- 1 + 1)
expression(2 *
    3)

可替换地:

> attributes(x[[2]])
NULL
> attributes(x[2])
$srcref
$srcref[[1]]
2 *
    3

eval(parse(..., keep.source=T))相比,这是否有任何实际影响,我只能说它可以,但不能想象它会发生的情况。

请注意,单独分组表达式也会导致srcref业务获得子集,这可能是有用的(...可能?)。