Skye Bender-deMoll
2013-Nov-22 21:43 UTC
[Rd] what is the correct way to force a copy of an object?
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
Kevin Ushey
2013-Nov-22 23:00 UTC
[Rd] what is the correct way to force a copy of an object?
You have to force the copy yourself. You can take advantage of R's reference counting to see if it is necessary at the C level as well. See the R extensions manual, 5.9.10, for more details: http://cran.r-project.org/doc/manuals/R-exts.html#Named-objects-and-copying; in particular, you can make use of the NAMED macro to see if multiple symbols are pointing at the same memory. I would recommend forcing the copy at the C level so that users don't run into such surprises; copying at the R level is unnecessary if that object is not otherwise used. -Kevin On Fri, Nov 22, 2013 at 1:43 PM, Skye Bender-deMoll <skyebend@skyeome.net>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. > > 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 > > ______________________________________________ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >[[alternative HTML version deleted]]
Duncan Murdoch
2013-Nov-22 23:41 UTC
[Rd] what is the correct way to force a copy of an object?
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 >
Maybe Matching Threads
- issues with dev.new avoiding RStudio plot device on unix?
- alternatives to do.call() when namespace is attached but not loaded?
- libcurl support and curlGetHeaders warning message in R CMD check
- Problems building package vignette: Sweave requires multiple passes to build document.
- issues with dev.new avoiding RStudio plot device on unix?