0

See example code:

myfunc <- function(inherit) {
  return(R6::R6Class("Derived", inherit = inherit)) 
}

Base <- R6::R6Class("Base")
Derived <- R6::R6Class("Derived", inherit = Base)
Derived2 <- myfunc(Base)
print(Derived)
print(Derived2)

Despite being technically equivalent, the first print statement reports:

<Derived> object generator
  Inherits from: <Base>
  Public:
    clone: function (deep = FALSE) 
  Parent env: <environment: 0x7fdf63a6cf18>
  Locked objects: TRUE
  Locked class: FALSE
  Portable: TRUE

While the second reports:

<Derived> object generator
  Inherits from: <inherit>
  Public:
    clone: function (deep = FALSE) 
  Parent env: <environment: 0x7fdf63afb8b8>
  Locked objects: TRUE
  Locked class: FALSE
  Portable: TRUE

How can I change the function myfunc so that the appropriately scoped name is used instead of the internal name inherit?

Stefano Borini
  • 138,652
  • 96
  • 297
  • 431

1 Answers1

0

The R6Class function uses non-standard evaluation. You could do

myfunc <- function(inherit) {
  eval.parent(substitute(R6::R6Class("Derived", inherit = inherit)))
}

to get the same output. That will resolve the inherit value to the value that was passed into the function

MrFlick
  • 195,160
  • 17
  • 277
  • 295
  • is there a way to know what uses non standard evaluation and what does not? There's no language visual or documentation information that I could infer about something being evaluated as is, or going through some form of metaprogramming – Stefano Borini Jun 21 '23 at 20:44
  • And thank you. You have been really helpful to me today. – Stefano Borini Jun 21 '23 at 20:45
  • I am having a bit of a problem, because my call is way more complex and it's also passing the parent env to the R6Class call. As a result it breaks in another way. How can I substitute only the inherit, but not the rest in the call? – Stefano Borini Jun 22 '23 at 10:57
  • There is no general way to know what uses nonstandard evaluation; there’s no documentation convention for that. I often just look at the source of the function. You can do a lot of complicated meta programming but it’s not clear what is required for your particular case. Maybe create a new question with more specifics that can be tested. – MrFlick Jun 22 '23 at 13:08
  • What I am trying to do is to generate a new R6 metaclass that adds shiny reactives to the resulting classes, while reusing the R6 functions. This works, but then I tried to handle inheritance as well. With inheritance, the call to the underlying R6 generator_funs$new does a get_inherit() and that fails because it's trying to look the verbatim name of the base class, but something in my code is wrong and I can't see it, in addition to the indirection inside the generator function. It's really hard for me to create something I can paste as a question. There's a lot of complexity going on. – Stefano Borini Jun 22 '23 at 13:54