Dear R-devs,
I'm working on a package where we have a function that modifies an
Object via .Call to a C function. Unfortunately in some situations this
counterintuitive modifies a previously made copy of the object passed to
the function. For example, if I first make an assignment to "copy" the
object,
b<-a
and then modify 'a' , the value of 'b' will be modified as well. I
understand that this is probably due to lazy evaluation--the copy of 'a'
is not made until the 'a' or 'b' instance is further modified. Peeking
at 'a' and 'b' using .Internal(inspect(a)) seems to confirm this. But
for some reason our function is not triggering the copy.
We have been able to kludge it to force a copy and behave as expected by
making a slight modification to the object before passing it to .Call:
modificationFun <- function(x){
x$ForceCopy<-NULL
x<-.Call("do_the_mod_in_c_R", package='mypackage')
invisible(x)
}
What is the correct way to force the copy to occur to avoid
inadvertently modifying both instances of the object? Neither force()
or eval() seem to do this.
Would it be faster to call duplicate(x) inside the C function instead of
forcing the copy at the R level?
thanks for your help,
-skye
what is the correct way to force a copy of an object?
3 messages · Skye Bender-deMoll, Kevin Ushey, Duncan Murdoch
An embedded and charset-unspecified text was scrubbed... Name: not available URL: <https://stat.ethz.ch/pipermail/r-devel/attachments/20131122/10856825/attachment.pl>
On 13-11-22 4:43 PM, Skye Bender-deMoll wrote:
Dear R-devs, I'm working on a package where we have a function that modifies an Object via .Call to a C function. Unfortunately in some situations this counterintuitive modifies a previously made copy of the object passed to the function. For example, if I first make an assignment to "copy" the object, b<-a and then modify 'a' , the value of 'b' will be modified as well. I understand that this is probably due to lazy evaluation--the copy of 'a' is not made until the 'a' or 'b' instance is further modified. Peeking at 'a' and 'b' using .Internal(inspect(a)) seems to confirm this. But for some reason our function is not triggering the copy.
No, lazy evaluation is a higher level concept. Your problem is that you are modifying something without guaranteeing nobody else is using it.
We have been able to kludge it to force a copy and behave as expected by
making a slight modification to the object before passing it to .Call:
modificationFun <- function(x){
x$ForceCopy<-NULL
x<-.Call("do_the_mod_in_c_R", package='mypackage')
invisible(x)
}
That's not the right way to fix this.
What is the correct way to force the copy to occur to avoid inadvertently modifying both instances of the object? Neither force() or eval() seem to do this. Would it be faster to call duplicate(x) inside the C function instead of forcing the copy at the R level?
duplicate(x) at the C level is the only way to do this. You can look at NAMED(x) to decide if this is necessary, or just do it unconditionally. Duncan Murdoch
thanks for your help, -skye
______________________________________________ R-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel