0

Given an R6 class Class1 with its initialize function, I would like to be able to pass an instance of the same class and return it directly.

Something like this:

if("Class1" %in% class(x)) x
else Class1$new(x)

But inside the initialize function of an R6 class, that should work like this

# This script does not work
# Definition of the class
Class1 = R6::R6Class("Class1",
                     public=list(
                       initialize = function(x){
                         # This line does not work
                         if("Class1"%in%class(x)) return(x)
                       }
                     ))
# Initiate an instance from scratch
foo = Class1$new()
# Initiate an instance through another instance
bar = Class1$new(foo)
# The two should be the same
identical(foo, bar)
#> TRUE
Duccio A
  • 1,402
  • 13
  • 27

1 Answers1

0

Under current state of R6 this seems to not be possible. Check the raw code github.com/r-lib/R6/blob/master/R/new.R . Most important are lines 154 where is initialization applied and 194 where public_bind_env is returned . The problem is that even with super assignment I think we could not overwrite it as all things are built here from a new empty env with own address. This solution which using a wrapper is widthly used in the market and it is doing what it should:

class1 <- function(x = NULL) {
  
  if(inherits(x, "Class1")) x else Class1$new(x)
    
}

Class1 = R6::R6Class("Class1",
                     public=list(
                       initialize = function(x = NULL){
                       }
                     ))
# Initiate an instance from scratch
foo = class1()
# Initiate an instance through another instance
bar = class1(foo)
# The two should be the same
identical(foo, bar)
#> TRUE

polkas
  • 3,797
  • 1
  • 12
  • 25
  • Thank you, but this is not what I asked. As the question states, I would like to be able to do this within the `initialize` function. – Duccio A Aug 05 '20 at 07:42
  • This might be not possible. Check the raw code https://github.com/r-lib/R6/blob/master/R/new.R .most important are lines 154 where is initialization applied and 194 where public_bind_env is returned . The problem is that even with super assignment I think we could not overwrite it as all things are built here from a new empty env with own address. I gave this solution as such are used in the market and it is doing what it should. – polkas Aug 06 '20 at 21:11
  • Thanks. Now, I see why adding a `return` statement in the `initialize` function does not work. Can you include your comment in the answer to explain why that is the only way to go? So I can mark it as accepted. – Duccio A Aug 10 '20 at 13:45
  • Done. It was pleasure to help. – polkas Aug 11 '20 at 16:37