Правила области действия R для вложенных функций

Я пытаюсь использовать лексическую область видимости R с двумя уровнями функций, но поведение в R 3.0.2 кажется неправильным.

foo = function() print(ii)
eye_foo = function( ) { 
    ii = 1  # (A)
    foo()
}
eye_foo()   # (B)
ii=2        # (C)
eye_foo()   # (D)

Я ожидаю, что (B) напечатает «1», привязываясь к переменной, определенной в (A). Вместо этого (B) выдает сообщение об ошибке «Ошибка печати (ii): объект 'ii' не найден». Однако после определения ii в (C) в глобальной области (D) печатает «2», игнорируя (A) в процессе.

Почему (А) игнорируется?


person Jacob Colvin    schedule 09.11.2013    source источник
comment
Я на самом деле тоже делаю что-то подобное, хотя это, вероятно, плохая практика. Мое решение — использовать выражения: foo <- expression(print(ii)); eye_foo2 <- function() {ii <- 1; eval(foo)}. Если вы используете eval(foo) где-либо, кроме eye_foo2, он будет использовать значение, найденное в глобальном окружении.   -  person Frank    schedule 09.11.2013


Ответы (1)


foo был определен в глобальной среде. Во время первого вызова eye_foo не было найдено значения ii в среде, где был создан foo. Затем вы сделали значение, которое нужно найти, и получили ожидаемые результаты. Просто как тот.

> environment(foo)
<environment: R_GlobalEnv>

 ?'function'
 ?globalenv

Обычно люди избегают этой головоломки, передавая аргументы функциям.

person IRTFM    schedule 09.11.2013
comment
спасибо, я запутался между лексической и динамической областью видимости. код должен был выглядеть так: eye_foo = function() { foo = function() print(ii) ii = 1 # (A) foo() } eye_foo() # (B) ii=2 # (C) eye_foo() # ( D), что дает ожидаемое поведение. - person Jacob Colvin; 09.11.2013
comment
Повторю еще раз: обычно люди избегают этой головоломки, передавая аргументы функциям. - person IRTFM; 09.11.2013