2015-04-04 17 views
1

我目前有一些問題了解eval函數的行爲 - 特別是當參數沒有提供給它時​​的enclos/third參數/使用默認參數parent.fame()。在默認參數中的奇怪行爲enclos = eval函數的parent.frame()

name <- function(x){ 
    print(substitute(x)) 
    t <- substitute(x) 
    eval(t, list(a=7), parent.frame()) 
} 
z <-5 
name(a+z) 
# returns 12, makes sense because this amounts to 
# eval(a+z, list(a=7), glovalenv()) 


# however the return here makes no sense to me 

    name2 <- function(x){ 
    print(substitute(x)) 
    t <- substitute(x) 
    eval(t, list(a=7)) # third/enclosure argument is left missing 
} 

z <-5 
name2(a+z) 
# Also returns 12 
我無法理解爲什麼第二次調用返回12.根據我的R理解

,第二個電話應該導致一個錯誤,因爲

1)EVAL默認的第三個參數enclos =父。 frame(),它沒有被指定。

2)因此,在eval的本地環境中評估parent.frame()。這是通過哈德利在When/how/where is parent.frame in a default argument interpreted?

3)確認。因此,最後一個表達式應該解析的eval(A + Z,列表(= 7),執行名字的環境)

4)本應該返回一個錯誤,因爲z沒有在名稱的執行環境中或列表中定義(a = 7)。

有人能解釋這個邏輯有什麼問題嗎?

+0

名稱的調用環境在這種情況下是全球環境,但總的來說你會錯的 – k13 2015-04-04 03:21:58

回答

1

z將在函數內部可用,因爲它在.GlobalEnv中定義。

簡而言之,

name <- function(x) { 
    print(z) 
} 
z <- 5 

name(z) 

# [1] 5 

因此,雖然a仍是未知的,直到eval(t, list(a=7))z已經可用。如果z未在name內定義,則將在.GlobalEnv中查找。可能違反直覺的是(a+z)未定義,除非您指定a的環境。但是對於z,沒有必要這樣做。

+0

這是由於詞法範圍的限制。得到它了。 – k13 2015-04-04 03:25:17

+0

是的,確切地說,你釘了它:詞彙範圍。 :) – 2015-04-04 03:38:52