Suppose I have these two functions:

fInner<-function()
{
   # Do some complicated stuff, and...
    I<<-I+1
}

fOuter<-function()
{
    I<-0
    fInner()
    print(I)
}

Calling fOuter() produces an error: Error in fInner() : object 'I' not found. I know, that one way of fixing it is to re-write the example into

fOuter<-function()
{
    fInner<-function()
    {
        I<<-I+1
    }
    I<-0
    fInner()
    print(I)
}

But what if I don't want to nest the functions that way? In my case fInner is a very heavy and complicated function (which I might want to move into my library), and fOuter is really an ad-hoc created function that defines one iterator. I will have many fOuter-class functions in my code, so nesting them will require duplicating the fInner inside every single little one iterator definition.

I suspect the solution has something to do with environments, but I don't know how to do it. Can anyone help?

有帮助吗?

解决方案

You need access to the environment associated with the fOuter function--where the call to fInner is. You can get this with parent.frame, and you can get and set variables with get and assign:

fInner<-function()
{
  assign("I", get("I", envir=parent.frame()) + 1, envir=parent.frame())
}

fOuter<-function()
{
  I<-0
  fInner()
  print(I)
}

See ?environment and ?parent.frame for more info.

But this is just to satisfy your curiosity! You seem to agree that this is not a good idea. Manipulating environments and names can quickly get complicated, and unless you're doing something truly complex, there's probably a better way.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top