Nested function environment selection

前端 未结 2 723
青春惊慌失措
青春惊慌失措 2020-12-24 04:24

I am writing some functions for doing repeated tasks, but I am trying to minimize the amount of times I load the data. Basically I have one function that takes some informat

相关标签:
2条回答
  • 2020-12-24 04:36

    To illustrate lexical scoping, consider the following:

    First let's create a sandbox environment, only to avoid the oh-so-common R_GlobalEnv:

    sandbox <-new.env()
    

    Now we put two functions inside it: f, which looks for a variable named x; and g, which defines a local x and calls f:

    sandbox$f <- function()
    {
        value <- if(exists("x")) x else "not found."
        cat("This is function f looking for symbol x:", value, "\n")
    }
    
    sandbox$g <- function()
    {
        x <- 123
        cat("This is function g. ")
        f()
    }
    

    Technicality: entering function definitions in the console causes then to have the enclosing environment set to R_GlobalEnv, so we manually force the enclosures of f and g to match the environment where they "belong":

    environment(sandbox$f) <- sandbox
    environment(sandbox$g) <- sandbox
    

    Calling g. The local variable x=123 is not found by f:

    > sandbox$g()
    This is function g. This is function f looking for symbol x: not found. 
    

    Now we create a x in the global environment and call g. The function f will look for x first in sandbox, and then in the parent of sandbox, which happens to be R_GlobalEnv:

    > x <- 456
    > sandbox$g()
    This is function g. This is function f looking for symbol x: 456 
    

    Just to check that f looks for x first in its enclosure, we can put a x there and call g:

    > sandbox$x <- 789
    > sandbox$g()
    This is function g. This is function f looking for symbol x: 789 
    

    Conclusion: symbol lookup in R follows the chain of enclosing environments, not the evaluation frames created during execution of nested function calls.

    EDIT: Just adding a link to this very interesting answer from Martin Morgan on the related subject of parent.frame() vs parent.env()

    0 讨论(0)
  • 2020-12-24 04:40

    You could use closures:

    f2 <- function(...){
       f1 <- function(...){
         print(var1)
       }
       var1 <- "hello"
       f1(...)
     }
     f2()
    
    0 讨论(0)
提交回复
热议问题