2016-07-13 23 views
3

Ich werde die Definition einer reinen Funktion von einem Datacamp course paraphrasieren von Hadley Wickham:programmatisch bestimmen, ob eine R-Funktion rein ist

  • Ausgänge hängen nur von Eingängen
  • Sie nichts außerhalb der Funktion ändern
    • keine Einstellung der globalen Variablen, kein Plot, kein Druck zu trösten, etc
  • Do h nicht Ave alle Eingänge, die für verschiedene Benutzer oder Sitzungen unterschiedlich sein können

Wie kann ich feststellen, ob eine bestimmte Funktion in einer automatisierten Weise rein ist? Ich habe über die Verwendung von args() gedacht, um nach Standardwerten zu suchen, aber dann bin ich nicht sicher, wie man überprüft, ob die Standardwerte globale Werte sind. Und ich habe darüber nachgedacht zu prüfen, aus welcher Bibliothek eine Funktion stammt, da einige bekanntermaßen meist reine Funktionen enthalten. Aber ich glaube nicht, dass das ein Test ist, der zu 100% funktioniert.

Alle Teilantworten wären ebenfalls hilfreich. Zum Beispiel: Wie kann ich feststellen, ob eine Funktion einen Plot erstellt? Wie kann ich feststellen, ob eine Funktion auf der Konsole gedruckt wird? Ich stelle mir vor, man könnte Testfälle entwerfen, aber viele positive Ergebnisse zu zeigen und keine negativen zu finden, ist auch kein endgültiger Beweis.

+0

Für die dritte, können wir annehmen, dass Eingaben, die in der Funktion gehen, selbst rein sind, z. B. nicht von etwas erzeugt werden, das sich je Benutzer unterscheiden kann, wie eine Umgebungsvariable bekommen? –

+0

Ich möchte nicht davon ausgehen, dass die Eingaben pro Benutzer unterschiedlich sein können. Es wäre schön, auch das überprüfen zu können. – Bobby

+0

'R CMD CHECK' führt einige davon aus - wenn Sie eine Funktion definieren, die versucht, ein Objekt zu verwenden, das nicht im verfügbaren Namespace ist, wird eine Warnung ausgegeben, etwa wie" keine sichtbare Bindung für Variable gefunden ". Sie könnten dort in den zugrunde liegenden Code schauen. – Gregor

Antwort

-2

Spaß Frage. Um viele dieser Probleme zu lösen, müssen Sie mit Umgebungen experimentieren. Lesen Sie this.

Hier ist eine einfache Lösung für Ihre erste Frage. Das Problem kann wie folgt definiert werden.

y <- 1 

f <- function(x){ 
    x + y 
} 

f(10) 
[1] 11 

Dies geschieht aufgrund der Scoping-Regeln von R. Wenn Sie f() aufrufen R innerhalb des Aufrufs der Funktion (lokale Umgebung) sucht, wenn es nicht finden kann, was es will, bewegt es sich in die übergeordnete Umgebung, die in diesem Fall der Arbeitsbereich ist (d. H. .GlobalEnv). Eine einfache Antwort ist also, dass Sie .GlobalEnv in eine andere Umgebung verschieben, nicht auf den Suchpfad f(), und rufen Sie dann f(). Zum Beispiel

y <- 1 

e <- new.env() #intitalizing a new environment 

#populating e with objects in `.GlobalEnv` 
for(i in ls()[!grepl("e",ls())]){ 
    assign(i, globalenv()[[i]], envir = e) 
} 

rm(list = ls()[!grepl("e",ls())]) #removing everything from the global environment that is not our environment e 

f <- function(x){ 
    x + y 
} 

f(10) 

Error in f(10) : object 'y' not found 

Lassen Sie uns nun die Objekte zuvor im globalen Umfeld bewegen

zurück
for(i in ls(envir = e)){ 
    assign(i, e[[i]]) 
} 

Es gibt vielleicht eine viel bessere Art und Weise die oben, aber zu tun, es ist ein Anfang. Ich bin mir auch sicher, dass die Antwort auf viele Ihrer Fragen erhalten wird, wenn Sie mit der Idee von Umgebungen herumspielen. Zum Beispiel könnte Ihre zweite Frage bezüglich globaler Variablen durch Vergleichen der globalen Umgebung vor und nach einem Funktionsaufruf beantwortet werden. Oder indem Sie den Call-Frame zur Überprüfung an die globale Umgebung übergeben.

+0

Danke, das ist ein nützliches Beispiel für die Umwelt. – Bobby

Verwandte Themen