¿Cuáles son las advertencias de usar source versus parse & eval?
(1)
Version corta
Puedo reemplazar
source(filename, local = TRUE, encoding = ''UTF-8'')
con
eval(parse(filename, encoding = ''UTF-8''))
sin ningún riesgo de rotura, para hacer que los archivos fuente UTF-8 funcionen en Windows?
Versión larga
Actualmente estoy cargando archivos fuente específicos a través de
source(filename, local = TRUE, encoding = ''UTF-8'')
Sin embargo, es bien sabido que esto no funciona en Windows , punto.
Como una solución, Joe Cheng sugirió usar en su lugar
eval(parse(filename, encoding = ''UTF-8''))
Esto parece funcionar bastante bien 1, pero incluso después de consultar el código fuente de la source
, no entiendo cómo difieren en un detalle crucial:
Tanto source
como sys.source
no simplemente parse
y luego eval
el contenido del archivo. En su lugar, analizan el contenido del archivo y luego iteran manualmente sobre las expresiones analizadas y las eval
una a una. No entiendo por qué esto sería necesario en sys.source
(la source
al menos lo usa para mostrar diagnósticos detallados, si así se indica, pero sys.source
no hace nada de eso ):
for (i in seq_along(exprs)) eval(exprs[i], envir)
¿Cuál es el propósito de eval
declaraciones por separado? ¿Y por qué se itera sobre los índices en su lugar directamente sobre las subexpresiones? ¿Qué otras advertencias hay?
Para aclarar: no me preocupan los parámetros adicionales de source
y parse
, algunos de los cuales pueden establecerse mediante opciones.
1 El motivo por el cual la source
se desconecta mediante la codificación, pero el parse
no se reduce a que la source
intente convertir el texto de entrada. parse
no hace tal cosa, lee el contenido del byte del archivo tal como está y simplemente marca su Encoding
como UTF-8
en la memoria.
Esta no es una respuesta completa, ya que aborda principalmente la parte seq_along
de la pregunta, pero es demasiado extensa para incluirla como comentarios.
Una diferencia clave entre el seq_along
seguido por el seq_along
[
vs just using for i in x
(que creo que es similar a seq_along
seguido por [[
lugar de [
) es que el primero conserva la expresión. Aquí hay un ejemplo para ilustrar la diferencia:
> 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)
Alternativamente:
> attributes(x[[2]])
NULL
> attributes(x[2])
$srcref
$srcref[[1]]
2 *
3
Si esto tiene algún impacto práctico al comparar con eval(parse(..., keep.source=T))
, solo puedo decir que podría, pero no puedo imaginar una situación en la que lo haga.
Tenga en cuenta que la expresión subconjunto por separado también conduce al subconjunto de obtención de negocios srcref
, que podría ser útil (¿quizás?).