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.

Reply via email to