On Thu, Jan 31, 2013 at 6:52 AM, Simon Zehnder <szehn...@uni-bonn.de> wrote: > Dear R community, > > I do know, that an R function is constructing a copy of any object passed as > argument into a function. I program on a larger S4 project for a package, and > I arrived at a point where I have to think a little harder on implementation > style (especially to spare users complex object handling). > > I have a function foo(), taking as input arguments two S4 objects of > different class type > > foo <- function(o1, o2) { > o1@att1 <- producesomething() > o2@att2 <- producesomethingelse() > > } > > Of course, this functions does not change the objects in the global > environment. Now I have two choices > > 1. Change the objects and return a list with both objects: > > foo <- function(o1, o2) { > o1@att1 <- producesomething() > o2@att2 <- producesomethingelse() > > l <- list(O1 = o1, O2 = o2) > return(l) > } > > This is cumbersome for users, as they have then to assign the objects inside > the returned list to the symbols used in the global environment. But it is > the way intended by R. > > 2. Change the objects of the global environment inside the function: > > foo <- function(o1, o2) { > o1@att1 <- producesomething() > o2@att2 <- producesomethingelse() > > assign("o1", o1, .GlobalEnv) > assign("o2", o2, .GlobalEnv) > } > > This is for users very practical, as the symbols used before refer now to > objects with changed attributes and can be used immediately. BUT: It is not > intended to be done like this. > > I spared any solution using one function for every single object type, as > this becomes even more cumbersome than choice 1 above, in my opinion. > > What is your opinion on the trade-off between user-friendly handling of > objects and R-intended programming style? Do I miss another choice, combining > both? > >
Another possibility is to create an environment component in your S4 class since those can be passed around as references: OO <- setClass("OO", representation(env = "environment")) setMethod("initialize", "OO", function(.Object) { .Object@env <- new.env() .Object }) setMethod("show", "OO", function(object) show(object@env$a)) o1 <- OO() o1@env$a <- 1 o2 <- OO() o2@env$a <- 2 o1 # 1 o2 # 2 swap <- function(o1, o2) { tmp <- o1@env$a o1@env$a <- o2@env$a o2@env$a <- tmp } swap(o1, o2) o1 # 2 o2 # 1 or if its feasible for you to change class systems Reference Classes already use environments: R <- setRefClass("R", fields = "a", methods = list( swap = function(o2) { tmp <- o2$a o2$a <- a a <<- tmp }, show = function() methods::show(a) ) ) r1 <- R$new(a = 1) r2 <- R$new(a = 2) r1 # 1 r2 # 2 r1$swap(r2) r1 # 2 r2 # 1 -- Statistics & Software Consulting GKX Group, GKX Associates Inc. tel: 1-877-GKX-GROUP email: ggrothendieck at gmail.com ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.