Подтвердить что ты не робот

Каковы предостережения об использовании источника и parse & eval?

Краткая версия

Можно ли заменить

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

с

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

без риска поломки, чтобы исходные файлы UTF-8 работали в Windows?

Длинная версия

В настоящее время я загружаю определенные исходные файлы через

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

Однако хорошо известно, что это не работает в Windows, полная остановка.

В качестве обходного пути предложил Джо Ченг, используя вместо этого

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

Это работает довольно хорошо 1 но даже после ознакомления с исходным кодом source я не понимаю, как они отличаются одной важной деталью:

Оба source и sys.source делают не просто parse, а затем eval содержимое файла. Вместо этого они анализируют содержимое файла, а затем перебирают вручную по разобранным выражениям и eval их по одному. Я не понимаю, почему это было необходимо в sys.source (sourceпо крайней мере использует его для отображения подробной диагностики, если это указано, но sys.source делает ничего подобного):

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

Какова цель выражения eval ing отдельно? И почему он вместо итераций перебирает вместо индексов непосредственно? Какие еще оговорки существуют?

Чтобы уточнить: меня не интересуют дополнительные параметры source и parse, некоторые из которых могут быть установлены с помощью опций.


1 Причина, по которой source отключена кодировкой, но parse не сводится к тому, что source пытается преобразовать входной текст. parse не делает этого, он считывает содержимое байта содержимого как есть и просто отмечает его Encoding как UTF-8 в памяти.

4b9b3361

Ответ 1

Это не полный ответ, поскольку он в первую очередь обращается к части вопроса 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 бизнес, который может быть полезен (возможно,?).