简短版本
可以换吗
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
都不简单地解析
然后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
。 p>
最佳答案
这不是完整的答案,因为它主要解决问题的 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
业务获取子集,这可能很有用(...也许?)。
关于r - 使用 source 与 parse 和 eval 相比有哪些注意事项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24454559/