[R] Call by reference: Was: Object orientation?

Jonathan Rougier J.C.Rougier at durham.ac.uk
Thu Mar 22 11:09:11 CET 2001


On 22 Mar 2001, Peter Dalgaard BSA wrote:

> "Henrik Bengtsson" <henrikb at braju.com> writes:
> 
> > To reply to Yves Gauvreau question (Jan 24, 2001) about how to set values
> > within function, it is possible to do without without using the "<<-"
> > assignment operator or other nasty tricks. I had the same problem and I did
> > a nasty workaround two weeks ago implementing the functionality of reference
> > variables, but today I "ran into" the [R] help page for ".Alias". With
> > .Alias one can immitate call by reference! Here is an example that shows how
> > it works:
> .....
> > set <- function(object, value) {
> >   this <- .Alias(object);
> >   this$value <- value;
> >   return (invisible());
> > }
> 
> It may work, but I wouldn't think it is documented to do so and could
> easily get blown away by an internal change (and *I'm* not going to put
> checks in to ensure that it keeps working)! 
> 
> If you really must do this kind of thing, try coding along the lines
> of
> 
> set<-function(object,value)
> 	eval.parent(substitute(object$value<-value))
> 
> Or use assign(), or even "<<-", at least that is well-defined. It can't
> get nastier than .Alias.

That's right!  You may want to consider using environments.  For example:

do.something.to.foo <- function(fooEnv, value)
{
  assign("value", value, envir=fooEnv)
  invisible(NULL)
}

foo <- new.env()
do.something.to.foo(foo, 1:10)
ls(envir=foo)
get("value", envir=foo)

If you want to write methods for foo you need to class it.  This is
quite possible if foo is an environment, ie

class(foo) <- "fooObj"

but after conversation with Luke Tierney in Vienna, in which he suggested
that simply classing an environment might be tricky (it might become
unclassed) he suggests that it might be better to wrap the environment
inside a list

fooList <- list(foo)
class(fooList) <- "fooObj"

and rewrite do.something.to.foo as

do.something.to.foo <- function(fooList, value)
{                                                                               
  assign("value", value, envir=fooList[[1]])
  invisible(NULL)                                                               
}                                                                               

Now you have

do.something.to.foo(fooList, 1:10)
get("value", envir=fooList[[1]])

and you can write a print method for the foo object as follows

print.fooObj <- function(fooList, ...)
{
  cat(paste("value: ", 
            paste(get("value", envir=fooList[[1]]), collapse=", "),
            "\n"
      )
  )
}

print(fooList)

Cheers, Jonathan.

Jonathan Rougier                       Science Laboratories
Department of Mathematical Sciences    South Road
University of Durham                   Durham DH1 3LE
tel: +44 (0)191 374 2361, fax: +44 (0)191 374 7388
http://www.maths.dur.ac.uk/stats/people/jcr/jcr.html

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._



More information about the R-help mailing list