Dear all,
I am confused about the inconsistent behaviors of `@<-` operator when
used in different ways. Consider the following example:
library(inline)
# Function to generate an externalptr object with random address
new_extptr <- cfunction(c(), '
SEXP val = PROTECT(ScalarLogical(1));
SEXP out = PROTECT(R_MakeExternalPtr(&val, R_NilValue, val));
UNPROTECT(2);
return(out);
')
setClass("S4ClassHoldingExtptr", contains = "externalptr")
subs_extptr_1 <- function(x) {
x at .xData <- new_extptr()
x
}
subs_extptr_2 <- function(x) {
x <- `@<-`(x, ".xData", new_extptr())
x
}
I expect functions "subs_extptr_1" and "subs_extptr_2"
should be
semantically identical. (is it right?)
But it seems that "subs_extptr_2" will modify its argument while
"subs_extptr_1" won't.
x <- new("S4ClassHoldingExtptr", new_extptr())
y <- x
y
# An object of class "S4ClassHoldingExtptr"
# <pointer: 0x7ffc60971eb0>
subs_extptr_1(x)
# An object of class "S4ClassHoldingExtptr"
# <pointer: 0x7ffc60974250>
x
# An object of class "S4ClassHoldingExtptr"
# <pointer: 0x7ffc60971eb0>
y
# An object of class "S4ClassHoldingExtptr"
# <pointer: 0x7ffc60971eb0>
As shown above, "subs_extptr_1" will not modify x or y.
subs_extptr_2(x)
# An object of class "S4ClassHoldingExtptr"
# <pointer: 0x7ffc60973f30>
x
# An object of class "S4ClassHoldingExtptr"
# <pointer: 0x7ffc60973f30>
y
# An object of class "S4ClassHoldingExtptr"
# <pointer: 0x7ffc60973f30>
However, "subs_extptr_2" will modify both x and y.
Is this behavior expected?
Thanks,
Jialin
> sessionInfo()
R version 3.4.1 (2017-06-30)
Platform: x86_64-suse-linux-gnu (64-bit)
Running under: openSUSE Tumbleweed
Matrix products: default
BLAS: /usr/lib64/R/lib/libRblas.so
LAPACK: /usr/lib64/R/lib/libRlapack.so
locale:
[1] LC_CTYPE=en_US.UTF-
8 LC_NUMERIC=C LC_TIME=en_US.UTF-8
[4] LC_COLLATE=en_US.UTF-8 LC_MONETARY=en_US.UTF-
8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-
8 LC_NAME=C LC_ADDRESS=C
[10] LC_TELEPHONE=C LC_MEASUREMENT=en_US.UTF-8
LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices
utils datasets methods base
other attached packages:
[1] inline_0.3.14 magrittr_1.5
loaded via a namespace (and not attached):
[1] compiler_3.4.1 tools_3.4.1 yaml_2.1.18 ulimit_0.0-3
luke-tierney at uiowa.edu
2018-Mar-18 14:54 UTC
[Rd] `@<-` modify its argument when slot is externalptr
On Sun, 18 Mar 2018, Jialin Ma wrote:> Dear all, > > I am confused about the inconsistent behaviors of `@<-` operator when > used in different ways. Consider the following example: > > library(inline) > > # Function to generate an externalptr object with random address > new_extptr <- cfunction(c(), ' > SEXP val = PROTECT(ScalarLogical(1)); > SEXP out = PROTECT(R_MakeExternalPtr(&val, R_NilValue, val)); > UNPROTECT(2); > return(out); > ') > > setClass("S4ClassHoldingExtptr", contains = "externalptr") > > subs_extptr_1 <- function(x) { > x at .xData <- new_extptr() > x > } > > subs_extptr_2 <- function(x) { > x <- `@<-`(x, ".xData", new_extptr()) > x > } > > I expect functions "subs_extptr_1" and "subs_extptr_2" should be > semantically identical. (is it right?)No. The are similar but not identical. It is not a good idea to call replacement functions directly and should be avoided. Doing so may need to become a runtime error or at least a warning in the future. Nevertheless, this is a bug in the implementation @<-.A simpler example is x <- setClass("foo", slots = "bar") x <- new("foo", bar = 1) y <- x y at bar ## [1] 1 `@<-`(x, bar, 2) y at bar ## [1] 2 Will be fixed soon in R-devel. Best, luke> x <- setClass("foo", slots = "bar") > x <- new("foo", bar = 1) > y <- x > `@<-`(x, bar, 2)An object of class "foo" Slot "bar": [1] 2> xAn object of class "foo" Slot "bar": [1] 2> x$barError in x$bar : $ operator not defined for this S4 class> x at bar[1] 2> But it seems that "subs_extptr_2" will modify its argument while > "subs_extptr_1" won't. > > x <- new("S4ClassHoldingExtptr", new_extptr()) > y <- x > y > # An object of class "S4ClassHoldingExtptr" > # <pointer: 0x7ffc60971eb0> > > subs_extptr_1(x) > # An object of class "S4ClassHoldingExtptr" > # <pointer: 0x7ffc60974250> > x > # An object of class "S4ClassHoldingExtptr" > # <pointer: 0x7ffc60971eb0> > y > # An object of class "S4ClassHoldingExtptr" > # <pointer: 0x7ffc60971eb0> > > As shown above, "subs_extptr_1" will not modify x or y. > > subs_extptr_2(x) > # An object of class "S4ClassHoldingExtptr" > # <pointer: 0x7ffc60973f30> > x > # An object of class "S4ClassHoldingExtptr" > # <pointer: 0x7ffc60973f30> > y > # An object of class "S4ClassHoldingExtptr" > # <pointer: 0x7ffc60973f30> > > However, "subs_extptr_2" will modify both x and y. > > Is this behavior expected? > > Thanks, > Jialin > > >> sessionInfo() > R version 3.4.1 (2017-06-30) > Platform: x86_64-suse-linux-gnu (64-bit) > Running under: openSUSE Tumbleweed > > Matrix products: default > BLAS: /usr/lib64/R/lib/libRblas.so > LAPACK: /usr/lib64/R/lib/libRlapack.so > > locale: > [1] LC_CTYPE=en_US.UTF- > 8 LC_NUMERIC=C LC_TIME=en_US.UTF-8 > [4] LC_COLLATE=en_US.UTF-8 LC_MONETARY=en_US.UTF- > 8 LC_MESSAGES=en_US.UTF-8 > [7] LC_PAPER=en_US.UTF- > 8 LC_NAME=C LC_ADDRESS=C > [10] LC_TELEPHONE=C LC_MEASUREMENT=en_US.UTF-8 > LC_IDENTIFICATION=C > > attached base packages: > [1] stats graphics grDevices > utils datasets methods base > > other attached packages: > [1] inline_0.3.14 magrittr_1.5 > > loaded via a namespace (and not attached): > [1] compiler_3.4.1 tools_3.4.1 yaml_2.1.18 ulimit_0.0-3 > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >-- Luke Tierney Ralph E. Wareham Professor of Mathematical Sciences University of Iowa Phone: 319-335-3386 Department of Statistics and Fax: 319-335-3017 Actuarial Science 241 Schaeffer Hall email: luke-tierney at uiowa.edu Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu
Lukas Stadler
2018-Mar-18 16:48 UTC
[Rd] `@<-` modify its argument when slot is externalptr
> On 18.03.2018, at 15:54, luke-tierney at uiowa.edu wrote: > > x <- setClass("foo", slots = "bar") > x <- new("foo", bar = 1) > y <- x > y at bar > ## [1] 1 > `@<-`(x, bar, 2) > y at bar > ## [1] 2 > > Will be fixed soon in R-devel. >I always assumed that this behavior is intentional, in order to make S4 "initialize" work efficiently. - Lukas [[alternative HTML version deleted]]
Hi Luke,
Thanks a lot for the explanation. I also noted that `@<-` will not
modify the argument when the slot is ".Data". For example
setClass("foo", contains = "numeric")
x <- new("foo", 2)
y <- x
y
# An object of class "foo"
# [1] 2
`@<-`(x, .Data, 42)
# An object of class "foo"
# [1] 42
x
# An object of class "foo"
# [1] 2
y
# An object of class "foo"
# [1] 2
Best regards,
Jialin
On Sun, 2018-03-18 at 09:54 -0500, luke-tierney at uiowa.edu
wrote:> On Sun, 18 Mar 2018, Jialin Ma wrote:
>
> > Dear all,
> >
> > I am confused about the inconsistent behaviors of `@<-` operator
> > when
> > used in different ways. Consider the following example:
> >
> > library(inline)
> >
> > # Function to generate an externalptr object with random address
> > new_extptr <- cfunction(c(), '
> > SEXP val = PROTECT(ScalarLogical(1));
> > SEXP out = PROTECT(R_MakeExternalPtr(&val, R_NilValue, val));
> > UNPROTECT(2);
> > return(out);
> > ')
> >
> > setClass("S4ClassHoldingExtptr", contains =
"externalptr")
> >
> > subs_extptr_1 <- function(x) {
> > x at .xData <- new_extptr()
> > x
> > }
> >
> > subs_extptr_2 <- function(x) {
> > x <- `@<-`(x, ".xData", new_extptr())
> > x
> > }
> >
> > I expect functions "subs_extptr_1" and
"subs_extptr_2" should be
> > semantically identical. (is it right?)
>
> No. The are similar but not identical. It is not a good idea to call
> replacement functions directly and should be avoided. Doing so may
> need
> to become a runtime error or at least a warning in the future.
>
> Nevertheless, this is a bug in the implementation @<-.A simpler
> example is
>
> x <- setClass("foo", slots = "bar")
> x <- new("foo", bar = 1)
> y <- x
> y at bar
> ## [1] 1
> `@<-`(x, bar, 2)
> y at bar
> ## [1] 2
>
> Will be fixed soon in R-devel.
>
> Best,
>
> luke
>
> > x <- setClass("foo", slots = "bar")
> > x <- new("foo", bar = 1)
> > y <- x
> > `@<-`(x, bar, 2)
>
> An object of class "foo"
> Slot "bar":
> [1] 2
>
> > x
>
> An object of class "foo"
> Slot "bar":
> [1] 2
>
> > x$bar
>
> Error in x$bar : $ operator not defined for this S4 class
> > x at bar
>
> [1] 2
>
> > But it seems that "subs_extptr_2" will modify its argument
while
> > "subs_extptr_1" won't.
> >
> > x <- new("S4ClassHoldingExtptr", new_extptr())
> > y <- x
> > y
> > # An object of class "S4ClassHoldingExtptr"
> > # <pointer: 0x7ffc60971eb0>
> >
> > subs_extptr_1(x)
> > # An object of class "S4ClassHoldingExtptr"
> > # <pointer: 0x7ffc60974250>
> > x
> > # An object of class "S4ClassHoldingExtptr"
> > # <pointer: 0x7ffc60971eb0>
> > y
> > # An object of class "S4ClassHoldingExtptr"
> > # <pointer: 0x7ffc60971eb0>
> >
> > As shown above, "subs_extptr_1" will not modify x or y.
> >
> > subs_extptr_2(x)
> > # An object of class "S4ClassHoldingExtptr"
> > # <pointer: 0x7ffc60973f30>
> > x
> > # An object of class "S4ClassHoldingExtptr"
> > # <pointer: 0x7ffc60973f30>
> > y
> > # An object of class "S4ClassHoldingExtptr"
> > # <pointer: 0x7ffc60973f30>
> >
> > However, "subs_extptr_2" will modify both x and y.
> >
> > Is this behavior expected?
> >
> > Thanks,
> > Jialin
> >
> >
> > > sessionInfo()
> >
> > R version 3.4.1 (2017-06-30)
> > Platform: x86_64-suse-linux-gnu (64-bit)
> > Running under: openSUSE Tumbleweed
> >
> > Matrix products: default
> > BLAS: /usr/lib64/R/lib/libRblas.so
> > LAPACK: /usr/lib64/R/lib/libRlapack.so
> >
> > locale:
> > [1] LC_CTYPE=en_US.UTF-
> > 8 LC_NUMERIC=C LC_TIME=en_US.UTF-8
> > [4] LC_COLLATE=en_US.UTF-8 LC_MONETARY=en_US.UTF-
> > 8 LC_MESSAGES=en_US.UTF-8
> > [7] LC_PAPER=en_US.UTF-
> > 8 LC_NAME=C LC_ADDRESS=C
> > [10] LC_TELEPHONE=C LC_MEASUREMENT=en_US.UTF-8
> > LC_IDENTIFICATION=C
> >
> > attached base packages:
> > [1] stats graphics grDevices
> > utils datasets methods base
> >
> > other attached packages:
> > [1] inline_0.3.14 magrittr_1.5
> >
> > loaded via a namespace (and not attached):
> > [1] compiler_3.4.1 tools_3.4.1 yaml_2.1.18 ulimit_0.0-3
> >
> > ______________________________________________
> > R-devel at r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-devel
> >
>
>