R правила за обхват за вложени функции

Опитвам се да използвам лексикалния обхват на R с 2 нива на функции, но поведението в 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) дава съобщение за грешка „Грешка в print(ii) : обектът „ii“ не е намерен“. Въпреки това, след дефиниране на ii в (C) в глобалния обхват, (D) отпечатва "2", игнорирайки (A) в процеса.

Защо (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