2010-11-02 10 views
6

Faceci, to doprowadza mnie do szału.Oszołamiające zachowanie `namiastki` w R

To działa zgodnie z oczekiwaniami:

eobj <- substitute(obj <- list(a, b), list(a = 32, b = 33)) 
eval(eobj) 
obj 
[[1]] 
[1] 32 

[[2]] 
[1] 33 

Teraz spróbuj tego:

efun <- substitute(fun <- function() a+ b, list(a = 32, b = 33)) 
str(efun) 
# language fun <- function() 32 + 33 
eval(efun) 
fun 
# function() a+ b 

Co tu się dzieje? Jak na Ziemi eval dostaje ręce na oryginalną formę wyrażenia?

Odpowiedz

8

Powoduje, że podczas drukowania fun jest to właściwie drukowane źródło funkcji (patrz attributes(fun)), które nie jest modyfikowane przez substitute.

Należy zauważyć, że po zdefiniowaniu a lub b w globalnym obszarze roboczym wynik funkcji jest taki sam.

Aktualny kod funkcji można zobaczyć pod numerem body(fun).

Albo porównać:

print.function(fun, useSource=FALSE) 
# function() 
# 32 + 33 
print.function(fun, useSource=TRUE) # Which is default 
# function() a+ b 
+0

Yap, to źródło rzeczywiście. Ale nadal jestem zdezorientowany, skąd pochodzi źródło? Źródło zabawy jest oddzielone od samego obiektu? Wyrażenie 'efun' nie ma żadnego odniesienia do źródła. 'eval' nie ma bezpośredniego dostępu do oryginalnej definicji. – VitoshKa

+0

Przypuszczam, że źródło jest ustawione, zanim działa 'substitute'. Oznacza to, że 'function' tworzy obiekt typu expression (language?) Ze źródłem argumentu, a następnie zastępuje wartości" a "i" b "w wyrażeniu z właściwymi wartościami lewe źródło nietknięte. – Marek

+2

'attr (fun," source ")' pokazuje źródło, które podtrzymuje dla twojej funkcji i co 'print' faktycznie drukuje. Jeśli nie ma atrybutu '" source "', to 'print' wyświetli aktualną funkcję. Zatem 'attr (fun," source ") <- NULL' spowoduje, że' print' wyświetli rzeczywistą funkcję, a nie zawartość '' source ''. Również 'options (keep.source = FALSE)' może być użyte do całkowitego wyłączenia tego zachowania, w którym to przypadku twoje funkcje nie otrzymają atrybutu '" source "'. –