[Rd] Defining environments within functions
Duncan Murdoch
murdoch at stats.uwo.ca
Fri Aug 29 13:20:27 CEST 2008
On 29/08/2008 6:52 AM, Giles Hooker wrote:
> Thanks,
>
> I think I over-emphasized the secondary function, but I can generate the
> scoping problem as follows. First, at the command line, I can get a
> function to access objects that were not in its arguments by
>
> ProfileEnv = new.env()
> hello.world = "Hello World"
> assign('hello.world',hello.world,3,envir=ProfileEnv)
>
> fn1 = function()
> {
> hw = get('hello.world',envir=ProfileEnv)
> print(hw)
> }
>
> and then call
>
> > fn1()
> [1] "Hello World"
>
>
> Now I want to define a wrapper function
>
> fn2 = function()
> {
> ProfileEnv = new.env()
> hello.world = "Hello World"
> assign('hello.world',hello.world,3,envir=ProfileEnv)
>
> fn1()
> }
>
> and if I try
>
> > rm(ProfileEnv) # Just to be safe
> > rm(hello.world)
> > fn2()
> Error in get("hello.world", envir = ProfileEnv) :
> object "ProfileEnv" not found
In fn2, you have a local variable called ProfileEnv. You defined fn1 in
the global environment, so it can't see it. Everything would work if
you defined fn1 within fn2.
A more natural way to do this is not to explicitly use environments.
Just use the natural lexical scoping in R. In the example below, I've
also added a counter variable, to answer your other question.
> buildfn1 <- function() {
+ hello.world <- "Hello World"
+ counter <- 0
+
+ fn1 <- function() {
+ print(hello.world)
+ counter <<- counter + 1 # note superassignment <<-
+ print(counter)
+ }
+
+ return(fn1)
+ }
>
> fn1 <- buildfn1()
> fn1()
[1] "Hello World"
[1] 1
> fn1()
[1] "Hello World"
[1] 2
Duncan Murdoch
>
> In my actual code, fn1() is really a call to
>
> optim(pars,ProfileErr,....)
>
> and hello.world are quantities that were calculated the last time that
> ProfileErr was called and that I want to keep track of.
>
> As an alternative simple example, how would I keep a counter for the
> number of times that optim (or any other generic optimizer) has called
> ProfileErr?
>
> giles
>
>>> How can I define environments within a function so that they are visible
>>> to calls to a sub-function?
>>>
>> I think you need to give a simplified, runnable example. (Or at least
>> runnable until it hits the scoping problem you've got.) "Sub-function"
>> isn't R terminology, and it's not clear what you mean by it.
>
More information about the R-devel
mailing list