我可以替换
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
的源代码之后,我也不明白它们在一个关键细节上的区别如何:
source
和sys.source
不只需parse
,然后eval
文件内容。相反,他们解析文件内容,然后手动迭代解析表达式,然后逐个eval
。我不明白为什么在sys.source
中必须这样做(source
至少使用它来显示详细的诊断,如果有这样的话;但是sys.source
做nothing of the kind):
for (i in seq_along(exprs)) eval(exprs[i], envir)
单独eval
语句的目的是什么?为什么它直接在子表达式上迭代索引?还有什么其他警告?
澄清:我不关注source
和parse
的其他参数,其中一些可以通过选项设置。
1 source
因编码而被parse
绊倒的原因并不是source
尝试转换输入的事实文本。 parse
没有这样的东西,它按原样读取文件的字节内容,只是将其Encoding
标记为内存中的UTF-8
。
答案 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
业务获得子集,这可能是有用的(...可能?)。