[R] How to change the value of a class slot
Duncan Murdoch
murdoch at stats.uwo.ca
Thu Jun 9 21:51:46 CEST 2005
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
More information about the R-help
mailing list