2016-01-26 11 views
5

Attualmente sto lavorando a un progetto in cui ho bisogno di creare un R6 class in R che può essere inizializzato in più di un modo. Mi chiedo quale sia il modo migliore per farlo. È possibile sovraccaricare la funzione $new()? O devo definire una funzione di supporto?R: come definire più costruttori per una classe R6?

Come esempio motivante: desidero avere due costruttori per una classe R6 MyClass con un campo names che può essere inizializzata utilizzando un Vector variable_names o un numero intero n_variables (nel qual caso inizializza un vettore predefinito di nomi) .

La funzionalità dovrebbe funzionare in questo modo:

#define the class (only has a constructor that accepts a vector of names) 
myClass <- R6Class("myClass", 
        public = list(
        names = NA, 
        initialize = function(names) { 
         if (!missing(names)) self$names <- names 
        }) 
) 

#create a test object using a vector of names 
variable_names = c("x","y") 
a = myClass$new(variable_names) 
a$names 
#> [1] "x y" 

#everything after here does not actually work (just to illustrate functionality) 
n_variables = 2; 
b = myClass$new(n_variables) 
b$names 
#> [1] "v1 v2" 

ho preso uno sguardo attraverso il Introductory vignette,, ma non sembra essere un modo chiaro per fare questo.

Idealmente, sto cercando una soluzione che non mi costringa a nominare gli argomenti (ad esempio, non devo fare qualcosa come myClass$new(names=variable_names)) e questo mi permette di verificare facilmente che gli input siano validi.

+0

Si può costruire una funzione di supporto wrapper che passerà il numero desiderato di nomi al costruttore? –

+0

@ 42- Scusa, sono un po 'confuso dal suggerimento. Come funzionerebbe? –

+0

Ho appena risposto a una domanda molto simile qui https://stackoverflow.com/questions/35881234/ –

risposta

4

È possibile utilizzare l'argomento punto-punto-punto (puntini di sospensione) per il costruttore che consente di passare un numero arbitrario di argomenti in funzione. Dopodiché devi convertire "..." nell'elenco e analizzare gli argomenti di input.


Ad esempio, si supponga di voler sovraccaricare il costruttore in base all'arità.

myClass <- R6Class("myClass", 
    public = list(
     name = NA, 
     age = NA, 
     favouriteFood = NA, 
     # Constructor overloaded by arity 
     initialize = function(...) { 
     arguments <- list(...) 
     switch(nargs(), 
      # one input argument 
      {self$name <- arguments[[1]]}, 
      # two input arguments 
      {self$name <- arguments[[1]] 
      self$age <- arguments[[2]]}, 
      # three input arguments 
      {self$name <- arguments[[1]] 
      self$age <- arguments[[2]] 
      self$favouriteFood <- arguments[[3]]} 
     ) 
     print(self) 
     }) 
) 

chiamando il costruttore ora ci dà

> a = myClass$new("john") 
<myClass> 
    Public: 
    age: NA 
    clone: function (deep = FALSE) 
    favouriteFood: NA 
    initialize: function (...) 
    name: john 
> a = myClass$new("john",35) 
<myClass> 
    Public: 
    age: 35 
    clone: function (deep = FALSE) 
    favouriteFood: NA 
    initialize: function (...) 
    name: john 
> a = myClass$new("john",35,"pasta") 
<myClass> 
    Public: 
    age: 35 
    clone: function (deep = FALSE) 
    favouriteFood: pasta 
    initialize: function (...) 
    name: john