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

Bert Gunter bgunter@4567 @end|ng |rom gm@||@com
Tue Dec 28 22:46:38 CET 2021


Are you aware that RStudio has its own Help resources at:

https://community.rstudio.com/

As they created and maintain  Shiny, perhaps you should post there.

Bert Gunter

"The trouble with having an open mind is that people keep coming along
and sticking things into it."
-- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )


On Tue, Dec 28, 2021 at 1:22 PM Grzegorz Smoliński
<g.smolinski1 using gmail.com> wrote:
>
> Thank you for all the comments. If this is not a problem, I would like
> to continue this thread as for me a lot of questions are still open.
> But if I should post other questions in different messages / topics,
> please let me know.
>
> I didn’t answer Ivan’s question previously, but yes, my desired result
> is indeed what debug() / debugonce() does and Ivan mentioned trace()
> earlier also, so I have tried this. I thought that trace() will be
> better in my case (than debug()) since I would like to be able to call
> trace() from one environment and insert browser() (using trace()) to
> the function defined in parent environment (still not sure if I
> understand this concept of environments).
>
> Even if I would like to use it in an shiny app, I have started with
> this example:
>
> ------------------------------
>
> fun1 <- function() {
>   a <-  1
>   a
> }
>
> fun2 <- function() {
>   fun1 <- function(){
>     b <- 2
>     b
>   }
>   trace(fun1, browser, where = globalenv())
> }
>
> fun1()
> fun2()
> fun1()
>
> --------------------------------
>
> So I was hoping to use trace inside child environment of global env,
> i.e. set browser() using trace() to the body of function defined in
> parent environment, but for sure I do not understand this since
> trace() in my example above is putting the browser() function inside
> fun1() function defined not in global environment, but in the body of
> fun2(). I.e. I'm starting to browse the fun1() function with the local
> variable 'b', not 'a' as I wanted.
>
> Can I ask for help with this? In other words, how can I refer to some
> function from the parent environment (not necessarily defined in the
> global environment) being in the child environment?
>
> Also, if I could ask - is the reversed operation possible? I mean -
> can I refer to some function from the child environment being in the
> parent environment? I guess not, because of ephemerality?
>
> As I mentioned, I'm thinking about all of this in the context of shiny
> app and the shiny app which consists of multiple files, modules. I'm
> thinking if I could refer to any function from any environment (or at
> least to any function in any parent environment) from one place (one,
> current environment) where I will call debug() or trace() to insert
> browser() at the beginning of this chosen function. And by "any
> function" I'm thinking about another thing problematic for me. If I
> consider this example:
>
> -------------------------------
> mod.R inside R/
> ---
>
> mod_UI <- function(id) {
> }
>
> name_mod <- function(input, output, session) {
>   fun1 <- reactive({
>     a  <-  1
>   })
> }
>
> ---
> app.R
> ---
>
> library(shiny)
>
> ui <- fluidPage(
>   mod_UI("mod"),
>   textOutput("env")
> )
>
> server <- function(input, output, session) {
>
>   name_mod("mod")
>
>   output$env <- renderPrint({
>     names(environment(name_mod))
>   })
>
>   observe({
>     #trace(fun1, browser, where = environment(name_mod))
>   })
> }
>
> shinyApp(ui, server)
> ---------------------------------------
> I tried to refer to the fun1 in environment(name_mod) - if I'm not
> wrong, this is my parent environment, where objects "mod_UI" and
> "name_mod" exist, but obviously I'm doing this wrong, right? Because
> here: "#trace(fun1, browser, where = environment(name_mod))" I have
> tried to refer to the module environment, but I should refer to the
> environment inside "name_mod". I don't know how to do this and here I
> also would like to ask for help.
>
> I know this may not be the best place for questions regarding shiny,
> but I think these questions are purely linked to environment topics.
>
> I also remember Bert's post about "body()" and yes, this seems to be a
> better idea than my first try in my first post, but "trace()" and
> "debug()" seem much easier as all I want is to insert browser(). But I
> just can't get it, how to refer to functions in (any) other
> environments.
>
> Thank you very much for all your help and I hope it is OK to keep asking :).
>
> pon., 27 gru 2021 o 18:28 Duncan Murdoch <murdoch.duncan using gmail.com> napisał(a):
> >
> > 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.
> >
> > Actually this isn't a bug in R, it is working as documented.  For a
> > detailed explanation, see the response to my bug report here:
> > https://bugs.r-project.org/show_bug.cgi?id=18269 .
> >
> > For a quick idea:  "complex assignments" are assignments where there is
> > a complex expression on the left hand side, e.g.
> >
> >    environment(test)$test <- ...
> >
> > The way these are documented to work (in the R Language Definition
> > manual) makes intuitive sense when you are working with regular R
> > objects, but environments are "mutable" objects:  assigning them to a
> > new name doesn't make a new copy, just a new reference.  That causes the
> > definition of the complex assignment above to work in an unintuitive way.
> >
> > Conclusion:  you should avoid using calls like environment(f) on the
> > left hand side of assignments, especially as part of a larger
> > expression.  Break up the statement into steps like I did below:
> >
> > >     e <- environment(test)
> > >     e$test <- eval(parse(text = "function() 2"))
> >
> > The same advice would apply to a function that returned an R6 object or
> > a mutable object from the methods package (which are really environments
> > in disguise), as well as some other exotic objects.
> >
> > Duncan Murdoch
>
> ______________________________________________
> R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.



More information about the R-help mailing list