2014-03-03 12 views
9

Ich spielte mit R herum und bemerkte einige Inkonsistenzen mit der globalen Umgebung, die Funktionsaufrufe von der tatsächlichen globalen Umgebung unterscheidet.Inkonsistenz mit der globalen Umgebung von R in einem Funktionsaufruf

Beachten Sie Folgendes:

> test = function() 
+ { 
+  print(environmentName(as.environment(-1))) 
+  print(ls(as.environment(-1))) 
+  print(environmentName(.GlobalEnv)) 
+  print(ls(.GlobalEnv)) 
+  as.environment(-1) 
+ } 
> foo = 1 
> ls() 
[1] "foo" "test" 
> test() 
[1] "" 
[1] "doTryCatch" "expr"  "handler" "name"  "parentenv" 
[1] "R_GlobalEnv" 
[1] "foo" "test" 
<environment: R_GlobalEnv> 

Innerhalb der Funktionsaufruf, as.environment(-1) gibt eine Umgebung, die es behauptet, ist <environment: R_GlobalEnv> aber wenn environmentName Aufruf auf Umwelt, sagte, sein Name ist ein leeres Zeichen. Darüber hinaus unterscheiden sich die Inhalte davon von denen in der echten globalen Umgebung. Was genau geht hier vor?

Ich bemerkte zuerst den Fehler mit mget innerhalb eines Aufrufs, da eine global definierte Variable nicht gefunden werden konnte. Dies scheint kontraintuitiv zu sein, da R normalerweise bei der Referenzierung einer Variablen innerhalb einer Funktion in den umgebenden Umgebungen nach oben sucht, bis eine Definition für eine Variable einschließlich der globalen Umgebung gefunden wird.

+2

Es scheint, dass 'environmentName' diesen Unterschied nicht zu zeigen, benötigt wird. Die zwei print-Anweisungen geben hier unterschiedliche Ergebnisse: 'test <- function() {e <- as.environment (-1); Druck (e); Drucken (als Umgebung (-1))}; test() ' –

+0

Vergleichen Sie auch:' print (as.environment (-1)); I (wie Umgebung (-1)); c (wie Umgebung (-1)). Sie alle geben unterschiedliche Ergebnisse, vermutlich in Bezug darauf, wie und wo sie ihre gelieferten Argumente auswerten, obwohl es mir nicht wirklich klar ist, was vor sich geht. Relevanter C-Level-Quellcode ist [hier] (https://github.com/wch/r-source/blob/trunk/src/main/envir.c#L2833) und [hier] (https: // github. com/wch/r-Quelle/Blob/Stamm/src/main/envir.C# L2789). (Das letzte Bit hat mich auf die Äquivalenz von 'as.environment (-1)' und 'pos.to.env (-1)' hingewiesen.) –

Antwort

4

Dies ist eine Folge der verzögerten Auswertung:

test <- function() { 
    e <- as.environment(-1) 

    list(
    lazy = ls(as.environment(-1)), 
    eager = ls(envir = e) 
) 
} 

foo <- 1 
test() 
#> $lazy 
#> [1] "doTryCatch" "expr"  "handler" "name"  "parentenv" 
#> 
#> $eager 
#> [1] "foo" "test" 
+2

Könntest du ein bisschen mehr ausarbeiten? Sollte nicht 'as.environment (-1)' im Eltern-Frame ausgewertet werden, da es sich um ein explizites Argument für 'ls' handelt? Wie kommt Faulheit dazu? Ich dachte, dass dies in erster Linie ein Problem bei der Definition von Schließungen war, ohne Argumente zu erzwingen, da die Schließung definiert ist. Entschuldige, dass du hier dicht bist. – BrodieG

+2

Das sieht immer noch aus wie ein Fehler in R. 'as.environment (-1)' sollte relativ zur Umgebung des Versprechens ausgewertet werden, aber es scheint nicht so. –

+1

Es ist definitiv kein Fehler. Ich werde morgen noch einige Erklärungen hinzufügen, wenn ich an einem Computer bin. – hadley

Verwandte Themen