On 6/9/2005 3:04 PM, Ross Boylan wrote:
On Wed, 2005-06-08 at 09:13 +0200, Uwe Ligges wrote:
[extensive deletions. Discussion concerned my desire to have a function change
the value
of an object in a way that had effects outside of the function, without
returning the object.]
>>You have to think about scoping rules and it
>>will be clear that the approach you are expecting is not a clean one in S.
>
> Could you say a bit more about that?
I meant the following simple example (not related to any object oriented
programming from the S point of view, but maybe well from your point of
view?):
Say you want a function foo() that simply incements the argument:
a <- 1
foo(a)
a # now is 2
But what happens if there is (more than) one "a" (in different
environments), but no "a" in the environment foo(a) is called from.
Which "a" do you want to change in this case? Seems to be rather dangerous.
Uwe Ligges
I believe your example assumes that foo is updating the outer a by
"cheating" and directly modifying enclosing environments. (I figure it
also needs to get the name of its actual argument to do this, which
would also involve slightly dirty tricks.) This does seem to be the only
way to do it in standard R.
In contrast, I wanted something like
foo<-function(formalArg){
formalArg <- new value
return something else
}
so that if I call foo(a), a has the new value after the call.
Unfortunately for me, that doesn't work. Call-by-value semantics imply
that it can't.
Here are some dirty ways to do it:
> foo <- function(FormalArg, value) {
+ assign(as.character(substitute(FormalArg)), value,
envir=sys.frame(sys.parent()))
+ }
> x
Error: Object "x" not found
> foo(x, 4)
> x
[1] 4
That one does the assignment in the caller's frame, not necessarily the
place that FormalArg was found. If you want to change a value that you
know exists, you could do something like this:
which.env <- function(name, envir = sys.frame(sys.parent())) {
if (!exists(name, envir)) stop('not found')
result <- envir
while (!is.null(result) && !exists(name, result, inherits = FALSE))
result <- parent.env(result)
return(result)
}
foo <- function(FormalArg, value) {
name <- as.character(substitute(FormalArg))
assign(name, value, which.env(name, sys.frame(sys.parent())))
}
Duncan Murdoch
______________________________________________
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html