S4 : faire une fonction spécialisée, avec héritage ?

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Arnaud Becheler
Messages : 64
Enregistré le : 20 Mar 2013, 13:47

S4 : faire une fonction spécialisée, avec héritage ?

Messagepar Arnaud Becheler » 02 Sep 2015, 11:47

Bonjour à tous et à toutes !

Conception orienté objet, Acte 3 :
S4pin : mais que diable allait-il faire dans cette galère ? ^^

Plus sérieusement, j'aimerais concevoir une classe virtuelle de fonction dont hériterait plusieurs autres classes spécialisées. Je cherche juste à faire des fonctions au comportement spécialisé : toutes ces fonctions correspondent à une entité logique dans le code (un modèle décliné en plusieurs variantes, qui renvoient une donnée de sortie de même type). Je crois que ça s'appelle un foncteur non ?

Mais je ne parviens pas à écrire la syntaxe :

1 - définir une classe virtuelle qui hériterait de la classe "function" : ça je sais faire

Code : Tout sélectionner

setClass("generalModel", contains = "function", representation = representation( "VIRTUAL"))


2 - définir des classes qui héritent de la précédente : ça je sais faire

Code : Tout sélectionner

setClass("unModel", contains = "generalModel")


3 - Instancier : ça je ne sais pas ! En plus il ne peut y avoir qu'une instance de ce nouveau type, et il est défini dès le début du programme.

Suis-je clair ? C'est assez dur à expliquer ! Je crois que j'ai quelques lacunes sur comment fonctionnent les fonctions dans le R orienté objet !
Si vous pouviez m'aider ce serait très chouette :)

Bien cordialement,
Arno
Es lo que hay

Mickael Canouil
Messages : 1315
Enregistré le : 04 Avr 2011, 08:53
Contact :

Re: S4 : faire une fonction spécialisée, avec héritage ?

Messagepar Mickael Canouil » 04 Sep 2015, 06:40

Bonjour,

je ne suis sûr d'avoir compris la question ou le problème...

ce que j'ai compris:
vous souhaitez définir une fonction qui renvoie le même type de résultats et ce pour toutes les classes d'objet qui hérite de "function", est-ce correct?
Mickaël
mickael.canouil.fr | rlille.fr

Arnaud Becheler
Messages : 64
Enregistré le : 20 Mar 2013, 13:47

Re: S4 : faire une fonction spécialisée, avec héritage ?

Messagepar Arnaud Becheler » 08 Sep 2015, 17:21

Heu disons que l'idée était de définir deux classes héritant de "function", admettons F et G.
Dans une méthode m1 ailleurs dans le code, je voudrais pouvoir mettre un argument de type "F", histoire de bloquer l'accès aux fonctions de classe G.
Et réciproquement dans une autre méthode.
Mais j'en demande peut-être un chouïa to much à R (je me prépare à glisser gentiment vers c++).
Es lo que hay

Mickael Canouil
Messages : 1315
Enregistré le : 04 Avr 2011, 08:53
Contact :

Re: S4 : faire une fonction spécialisée, avec héritage ?

Messagepar Mickael Canouil » 09 Sep 2015, 07:05

Dans ce cas là (si j'ai bien compris^^), il suffit de définir le champ signature de setMethod

Code : Tout sélectionner

setMethod(f = "nomdemethod", signature = "F", definition = function(x){ print("Method pour F") })
setMethod(f = "nomdemethod", signature = "G", definition = function(x){ print("Method pour G")  })


Comme la méthode n'est définie que pour les arguments du type fournit dans "signature", si l'argument est autre, soit R renvoie qu'il n'existe pas de méthode pour ce type d'objet, soit vous avez défini une méthode spécifique et il exécute celle-ci.
Mickaël
mickael.canouil.fr | rlille.fr

Arnaud Becheler
Messages : 64
Enregistré le : 20 Mar 2013, 13:47

Re: S4 : faire une fonction spécialisée, avec héritage ?

Messagepar Arnaud Becheler » 09 Sep 2015, 17:24

Alors je me suis mal expliqué ^^ Merci de ta réponse :)
Pour cet aspect là du problème, j'étais ok.
Ce que je vois moins bien c'est au moment d'instancier un objet de ma nouvelle classe G.
typiquement je ferais pour la classe "function" :

Code : Tout sélectionner

 foo1 <- function(x, arg){...}
class(foo1) # = "function"


et la question c'est comment construire GFunction pour que :

Code : Tout sélectionner

foo2 <- GFunction(x, arg){...}
class(foo2) # = "G"


Une idée que j'avais eu était de construire d'abord un objet de classe function, puis juste de le promouvoir comme un objet de classe G. Mais je ne savais pas comment faire. Là en l'écrivant, je suis en train de penser que "coerce" doit marcher non ?
Il suffit "juste" de définir un constructeur pour la classe G qui soit capable de construire à l'intérieur un objet de type "function" et de lui appliquer coerce vers "G". Sauf que ça me paraît pas très naturel (déconstruire/reconstruire/promouvoir...ça implique de bricoler les arglist, expr et value non ? ) ¬¬
Où est-ce que je me plante ?
En tout cas merci pour ton acharnement à essayer de me comprendre x)
Es lo que hay

Mickael Canouil
Messages : 1315
Enregistré le : 04 Avr 2011, 08:53
Contact :

Re: S4 : faire une fonction spécialisée, avec héritage ?

Messagepar Mickael Canouil » 15 Sep 2015, 12:13

Disons que dans ce cas, je serais parti sur les constructeurs, je m'explique.

Selon l'énoncé, la classe "G" hérite de "function", ça pourrait être quelque chose comme suit:

Code : Tout sélectionner

setClass(
    Class = "function",
    representation = representation(
        Data = "data.frame",
        arg = "list"
    ),
    prototype = prototype(
        Data = data.frame(),
        LD = list()
    )
)

setClass(
    Class = "G",
    representation = representation(
        x = "numeric",
        y = "numeric",
        par = "function"
    ),
    prototype = prototype(
        x = numeric(),
        y = numeric(),
        par = new("function", ...) # Or method, better if it is
    )
)

Au final, le constructeur de "G" devra:
1- remplir les champs "x", "y"
2- remplir le champ "par" directement en utilisant le constructeur de "function".


Ce jeu d'héritage permet de définir des méthodes pour "function" qui pourront être adaptées pour "G".

Le cas le plus absurde serait:

Code : Tout sélectionner

setClass(
    Class = "function",
    representation = representation(
        Data = "data.frame",
        arg = "list"
    ),
    prototype = prototype(
        Data = data.frame(),
        LD = list()
    )
)
setClass(
    Class = "G",
    representation = representation(
        par = "function"
    ),
    prototype = prototype(
        par = new("function", ...) # Or method
    )
)
setMethod(f = "show", signature = "function", definition = function (x) { show(x) })
setMethod(f = "show", signature = "G", definition = function (x) { show(x@par) })
Mickaël
mickael.canouil.fr | rlille.fr


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité