[R] How to modify object's code living in some environment?

Duncan Murdoch murdoch@dunc@n @end|ng |rom gm@||@com
Mon Dec 27 14:27:28 CET 2021


On 27/12/2021 8:25 a.m., Duncan Murdoch wrote:
> On 27/12/2021 8:06 a.m., Grzegorz Smoliński wrote:
>> Hi,
>>
>> I know it is possible to find the environment in which some object
>> lives using the 'environment()' function and the name of this object,
>> but how to modify code of this object after this? Below is MRE:
> 
> You are misunderstanding the relation between environments and
> functions.  However, your understanding is also being messed up by a bug
> in R, so it's not entirely your fault.
> 
> More details below:
>>
>> test <- function() 1
>>
>> test() # 1
>>
>> environment(test)$test <- eval(parse(text = "function() 2"))
> 
> First:  while it's usually true that function f will be found in
> environment(f), these are really separate concepts.
> 
> The environment of a function is where it will start looking for
> non-local variables. It is initially the environment in which the
> function definition is evaluated.
> 
> The environment holding a function can be completely different.  This
> most commonly shows up when you have functions that create other
> functions.  For example,
> 
>     factory <- function(x) {
>       force(x)
>       function() print(x)
>     }
> 
>     f <- factory(3)
>     f()
> 
> which will print 3.  Here environment(f) is the evaluation frame of the
> call to factory(3), while f is not stored there, it is stored in the
> global environment.  (If you run ls(environment(f)) you won't see "f"
> listed, only "x".)
> 
> In your first line "test <- function() 1" you create a function named
> test in the global environment whose environment is also the global
> environment.
> 
> The third line should do what you want, i.e. put the new definition into
> the environment of the test function, using the name test, but it
> doesn't:  I think that's a bug in R.  It should be equivalent to
> 
>     .GlobalEnv$test <- eval(parse(text = "function() 2"))
> 
> or
> 
>     test <- eval(parse(text = "function() 2"))
> 
> but as you saw, it's not.  They do what you were expecting your third
> line to do.
> 
>>
>> test() # still 1
>>
>> .GlobalEnv$test <- eval(parse(text = "function() 3"))
>>
>> test() # 3
>>
>> The context is I have shiny app which code I would like to modify (add
>> something) and the only way to refer to this environment I know is to
>> use 'environment()' (as I see, those functions do not live in
>> .GlobalEnv), but as you can see above, I can't use it to modify the
>> code.
> 
> You can, as long as you work around the bug in R.  Just change that
> third line into two statements:
> 
>     e <- environment(test)
>     e$test <- eval(parse(text = "function() 2"))
> 

And I forgot to mention, as Ivan did, that this might not do what you 
want, because of the difference in the concepts of "environment(f)" and 
"environment where f is found".

Duncan Murdoch



More information about the R-help mailing list