1

I'm new to the R6 classes and i'm starting to get the hang of things. However, i'm currently nesting classes and i want to loop through a list of specific nested classes. So, as shown in the example below, some of the elements of a Person class are classes themselves, like the BodyPart class, which is incorporated via the arm, leg and head elements of the Person class. The Person class also contains a list of subclasses of interest (bodyParts, as a way of grouping them). The getVolume function in the Person class loops through the list and catches the specific subclasses of interest.

A small and silly example:

BodyPart <- R6::R6Class(classname = "BodyPart",
                        public = list(
                          width = numeric(),
                          volume = numeric(),
                          initialize = function(name = NA, width = 3, volume = 2){
                            self$name <- name
                            self$width <- width
                            self$volume <- volume
                          }
                          
                        )
)

Person <- R6::R6Class(classname = "Person",
                      public = list(
                        name = character(),
                        age = numeric(),
                        bodyParts = list(),
                        arm = environment(),
                        leg = environment(),
                        head = environment(),
                        initialize = function(name = NA, age = NA, bodyParts = list("arm", "leg", "head"), arm = NA, leg = NA, head = NA){
                          self$name <- name
                          self$age <- age
                          self$bodyParts <- bodyParts
                          self$arm <- arm
                          self$leg <- leg
                          self$head <- head
                        }, 
                        getVolume = function(){
                          for(bodyPart in self$bodyParts){
                            volume <- get(bodyPart)$volume
                            print(paste(bodyPart, volume))
                          }
                        }
                      )
)

LongArm <- BodyPart$new()
MediumLeg <- BodyPart$new()
CubeHead <- BodyPart$new()

Person <- Person$new(name = "Jake", age = 20, arm = LongArm, leg = MediumLeg, head = CubeHead)
Person$getVolume()

The code does work for classes in general (those defined outside of the Person class), but not for the attached subclasses, since i do not know how to incorporate the self$ portion in the loop.

I know the example above is a bit silly and indirect, but the idea is the same. The final plan is to allow for a custom number of subclasses (using ...), which can be selected by the bodyParts list, allowing for functions to interact with a custom number of specific subclasses at once.

Does anyone know how to select specific subclasses within a R6 class? Or might a different approach be more effective for this problem?

Many thanks in advance!

Greacus
  • 35
  • 5

1 Answers1

0

I found quite a simple workaround: list all the bodyparts (subclasses) together and let the class take the list as a property/element. Then loop through the self$list to get whatever value you want.

so this would be:

BodyPart <- R6::R6Class(classname = "BodyPart",
                        public = list(
                          width = numeric(),
                          volume = numeric(),
                          initialize = function(name = NA, width = 3, volume = 2){
                            self$name <- name
                            self$width <- width
                            self$volume <- volume
                          }
                          
                        )
)

Person <- R6::R6Class(classname = "Person",
                      public = list(
                        name = character(),
                        age = numeric(),
                        bodyParts = list(),
                        initialize = function(name = NA, age = NA, bodyParts = NA){
                          self$name <- name
                          self$age <- age
                          self$bodyParts <- bodyParts
                        }, 
                        getVolume = function(){
                          for(bodyPart in self$bodyParts){
                            print(bodyPart$volume)
                          }
                        }
                      )
)

LongArm <- BodyPart$new()
MediumLeg <- BodyPart$new()
CubeHead <- BodyPart$new()

bodyPartsList <- c(LongArm, MediumLeg, CubHead)

Person <- Person$new(name = "Jake", age = 20, BodyParts = bodyPartsList)
Person$getVolume()

Hope this also helps for others as well!

Greacus
  • 35
  • 5