S3 et S4 semble être la langue officielle (c'est à dire intégrée) approches de la programmation orientée-objet. J'ai commencé à utiliser une combinaison de S3 avec des fonctions intégrées dans le constructeur de la fonction/méthode. Mon objectif était d'avoir un objet$method() la syntaxe de type, de sorte que j'ai semi-privées. Je dis semi-privé, car il n'y a aucun moyen de vraiment les cacher (autant que je sache). Voici un exemple simple qui ne fait pas faire quoi que ce soit:
#' Constructor
EmailClass <- function(name, email) {
nc = list(
name = name,
email = email,
get = function(x) nc[[x]],
set = function(x, value) nc[[x]] <<- value,
props = list(),
history = list(),
getHistory = function() return(nc$history),
getNumMessagesSent = function() return(length(nc$history))
)
#Add a few more methods
nc$sendMail = function(to) {
cat(paste("Sending mail to", to, 'from', nc$email))
h <- nc$history
h[[(length(h)+1)]] <- list(to=to, timestamp=Sys.time())
assign('history', h, envir=nc)
}
nc$addProp = function(name, value) {
p <- nc$props
p[[name]] <- value
assign('props', p, envir=nc)
}
nc <- list2env(nc)
class(nc) <- "EmailClass"
return(nc)
}
#' Define S3 generic method for the print function.
print.EmailClass <- function(x) {
if(class(x) != "EmailClass") stop();
cat(paste(x$get("name"), "'s email address is ", x$get("email"), sep=''))
}
Et certains de code de test:
test <- EmailClass(name="Jason", "jason@bryer.org")
test$addProp('hello', 'world')
test$props
test
class(test)
str(test)
test$get("name")
test$get("email")
test$set("name", "Heather")
test$get("name")
test
test$sendMail("jbryer@excelsior.edu")
test$getHistory()
test$sendMail("test@domain.edu")
test$getNumMessagesSent()
test2 <- EmailClass("Nobody", "dontemailme@nowhere.com")
test2
test2$props
test2$getHistory()
test2$sendMail('nobody@exclesior.edu')
Voici un lien vers un blog que j'ai écrit au sujet de cette approche: http://bryer.org/2012/object-oriented-programming-in-r je serais heureux de recevoir vos commentaires, critiques et suggestions à cette approche que je ne suis pas convaincu moi-même si c'est la meilleure approche. Toutefois, pour le problème que j'essayais de résoudre, il a beaucoup travaillé. Plus précisément, pour le mainteneur de paquet (http://jbryer.github.com/makeR) je n'ai pas envie aux utilisateurs de modifier les champs de données directement parce que j'avais besoin pour s'assurer qu'un fichier XML qui représentait mon objet de l'état de rester en synchronisation. Il a parfaitement fonctionné tant que les utilisateurs respectent les règles que j'ai aperçu dans la documentation.