I think I've found a workaround that avoids the two problems in the replacement function approach. With the definitions of list and [<-.result shown, one can write list[a,b] on the left side of an assignment where the right side of the assignment evaluates to a list of the same length (or if the list on the right side is shorter then the otherwise unfilled variables are set to NA and if the list on the right side is longer the excess entries are ignored). Unlike the previous workaround using a replacement function, one can have a variable number of arguments to list[] and the first argument to list[] no longer has to be predefined.
list <- structure(NA,class="result") "[<-.result" <- function(x,...,value) { args <- as.list(match.call()) args <- args[-c(1:2,length(args))] length(value) <- length(args) for(i in seq(along=args)) eval(substitute(x <- v,list(x=args[[i]],v=value[[i]])),env=sys.frame(-1)) x } # it is used like this: x <- 1:4 fn <- function() list("zz",99) list[a,x[2]] <- fn() Gabor Grothendieck <ggrothendieck <at> myway.com> writes: : : Here are two approaches assuming foo is "zz" and bar is 3. : : FIRST : : You could pass the return variables in the argument list and then : assign them in the caller's frame like this: : : fn <- function(x,y) { : assign(as.character(substitute(x)), "zz", sys.frame(-1)) : assign(as.character(substitute(y)), 3, sys.frame(-1)) : } : fn(a,b) # sets a to "zz" and b to 3 : : SECOND : : You can make this a bit prettier, though not perfect, like this: : : "list2<-" <- function(x,y,value) { : assign(as.character(substitute(y)), value[[2]], sys.frame(-1)) : value[[1]] : } : fn <- function()list("zz",3) : a <- 1 # first arg must exist prior to invoking list2. Its value not important. : list2(a,b) <- fn() : : The two problems with list2 are: : : 1. the first argument must exist prior to invoking list2 although its : actual value is immaterial since it just gets overwritten anyways. : : 2. It only works for 2 args although you could write a list3, list4, etc. : : Maybe someone could comment on these deficiencies. : : Jack Tanner <ihok <at> hotmail.com> writes: : : : : : I know that if I have a function that returns multiple values, I should : : do return(list(foo, bar)). But what do I do on the recieving end? : : : : fn <- function(x) { : : return(list(foo, bar)) : : } : : : : I know that at this point I could say : : : : values.list <- fn(x) : : : : and then access : : : : values.list[1] : : values.list[2] : : : : But that's hideous. I'd rather be able to say something like : : : : list(local_foo, local_bar) <- fn(x) : : : : and have the right thing happen. I realize that it's my responsibility : : to not screw up and say instead : : : : list(local_bar, local_foo) : : : : Any suggestions? : : : : -JT : : : : ______________________________________________ : R-help <at> stat.math.ethz.ch mailing list : https://www.stat.math.ethz.ch/mailman/listinfo/r-help : PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html : : ______________________________________________ [EMAIL PROTECTED] mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html