2016-03-21 4 views
0

J'ai une classe de référence que je pourrais utiliser comme objet dans une autre classe de référence. Exemple:R: Champs dans les classes de référence de type Classe de référence

class_1 <- setRefClass(Class = "class_1" 
    , fields = list(nickname = "character", version = "character") 
    , methods = list(
     initializer = function(nickname, version) { 
     nickname <<- nickname 
     version <<- version 
     } 
    ) 
) 

class_2 <- setRefClass(Class = "class_2" 
    , fields = c(version = "character" 
        , nickname = "character" 
        , class_1_item = "class_1") 
    , methods = list(
     initializer = function(class_2_nickname = "B", class_2_version = "V2") { 
     class_1_item <<- class_1$new(class_2_nickname, class_1_version) 
     nickname <<- class_2_nickname 
     version <<- class_2_version 
     } 
    ) 

) 

####### 

class_2_obj <- class_2$new(nickname = "A", version = "V1") 

class_1_obj <- class_1$new(nickname = "A", version = "V1") 

class_2_obj2 <- class_2$new() 

Quand j'invoque la première ligne après les marques de commentaire, il crée un objet Classe_2 ​​avec un objet class_1 à l'intérieur de celui-ci, mais il initialise jamais les champs à l'class_1_item d'objet qui a son constructeur appelé dans le cadre de la première ligne. Pourtant quand j'appelle le constructeur directement dans la ligne 2 (en dehors du constructeur de la classe 2), il initialise ces champs très bien. Enfin, lorsque j'appelle le constructeur à la ligne 3 sans arguments, il n'obtient même pas les arguments par défaut et laisse tout nul. Je pense qu'il y a quelque chose de fondamental à propos des classes R qui les rend complètement différentes des classes C/Python/Java que je ne reçois pas. Je ne comprends pas ce que l'objet "class_1" appelle un objet lorsque j'utilise l'opérateur d'affectation avec $ setRefClass() $. De plus, j'ai l'impression de ne pas comprendre dans quels cas l'opérateur "< < -" est destiné à être utilisé dans ce contexte par rapport à l'opérateur "< -".

Qu'est-ce qui me manque?

Répondre

1

Le processus d'initialisation pour les classes de référence S4 m'a toujours confondu, donc il peut y avoir une meilleure solution. Vous devez utiliser <<- au lieu de <- car l'opérateur d'affectation normal ne ferait qu'une affectation locale - locale à votre méthode init. Cependant, vous voulez remplacer les champs de l'objet qui se trouvent dans l'environnement englobant de toute méthode définie pour votre objet. Pour effectuer une affectation dans l'environnement inclus, vous avez besoin de <<-. Une alternative est l'utilisation de .self que j'utilise pour l'illustration ci-dessous - pour autant que je sache, il n'y a pas de différence autre que la préférence.

J'ai également modifié votre exemple de sorte que le processus init s'aligne avec vos attentes. La section initialize de la fonction setRefClass peut valoir la peine d'être lue. Je n'ai aucune compréhension de ce qu'une méthode initializer comme vous l'avez défini contrairement à la méthode initialize mais je crois que c'est ce dernier que vous voulez vraiment. De plus, je n'ai aucun sens sur l'objet auquel vous faites référence mais qui semble être défini nulle part. Mais j'espère que ce qui suit aidera de toute façon.

class_1 <- setRefClass( 
    Class = "class_1", 
    fields = list(nickname = "character", version = "character"), 
    methods = list(
     initialize=function(nickname = NA_character_, version = NA_character_) { 
      .self$nickname <- nickname 
      .self$version <- version 
     } 
    ) 
) 

class_2 <- setRefClass(
    Class = "class_2", 
    fields = c(
     version = "character", 
     nickname = "character", 
     class_1_item = "class_1" 
    ), 
    methods = list(
     initialize=function(nickname = NA_character_, version = NA_character_) { 
      .self$class_1_item <- class_1$new(nickname, version) 
      .self$nickname <- nickname 
      .self$version <- version 
     } 
    ) 
) 
+0

Merci! Cela doit être une faute de frappe, alors - $ intializer $ devrait être $ initialize $. – ecksc