使用源代码与解析和评估有什么注意事项?

Kon*_*lph 43 eval r

精简版

我可以更换吗?

source(filename, local = TRUE, encoding = 'UTF-8')
Run Code Online (Sandbox Code Playgroud)

eval(parse(filename, encoding = 'UTF-8'))
Run Code Online (Sandbox Code Playgroud)

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

长版

我目前正在通过加载特定的源文件

source(filename, local = TRUE, encoding = 'UTF-8')
Run Code Online (Sandbox Code Playgroud)

但是,众所周知,这不适用于Windows,完全停止.

作为一种解决方法,Joe Cheng建议使用

eval(parse(filename, encoding = 'UTF-8'))
Run Code Online (Sandbox Code Playgroud)

这看起来效果很好1,但即使在查阅了源代码之后source,我也不明白它们在一个关键细节上的区别:

双方sourcesys.source不是简单地parse,然后eval将文件内容.相反,他们解析文件内容,然后在解析的表达式上手动迭代,然后eval逐个迭代.我不明白为什么这是必要的sys.source(source至少用它来显示详细的诊断,如果有这样的指示;但sys.source不做任何类似的事情):

for (i in seq_along(exprs)) eval(exprs[i], envir)
Run Code Online (Sandbox Code Playgroud)

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

为了澄清:我关心其他参数sourceparse,其中一些可以通过选项进行设置.


1source由编码引起的原因,但parse不是归结为source尝试转换输入文本的事实.parse没有这样的事情,它按原样读取文件的字节内容,并简单地将其标记EncodingUTF-8内存.

Bro*_*ieG 5

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

seq_along后跟[vs仅使用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)
Run Code Online (Sandbox Code Playgroud)

或者:

> attributes(x[[2]])
NULL
> attributes(x[2])
$srcref
$srcref[[1]]
2 *
    3
Run Code Online (Sandbox Code Playgroud)

相比之下,这是否有任何实际影响eval(parse(..., keep.source=T)),我只能说它可以,但无法想象它的情况.

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