My question is just to understand how one feature of the R language works. In "the R language definition" coming with any good release of R, there is something explaining how, for example, the setting of an element of a vector works with something that looks like an assignment but is not so straightforward:
x[3:5] <- 13:15
is a shortcut for:
`*tmp*` <- x
x <- "[<-"(`*tmp*`, 3:5, value=13:15)
rm(`*tmp*`)
What I don't understand is the reason why using an intermediate symbol *tmp*
and not directly do the thing with the setter function.
x <- "[<-"(x, 3:5, value=13:15)
Until now I was suspecting that it has something to do with garbage collection but as this one has significantlly changed with the v4 and as the documentation did'nt change I am now supecting that I was wrong. Can somebody explain?
Thanks
OK, first let's show that the description is quite literal: `*tmp*`
is actually created.
`*tmp*` <- NULL
lockBinding("*tmp*", .GlobalEnv)
x[3:5] <- 13:15
#Error: cannot change value of locked binding for '*tmp*'
unlockBinding("*tmp*", .GlobalEnv)
Now, the language definition explains that the mechanism is quite general and also used for more complex assignments. Here is an example that actually creates different results if you don't use a `*tmp*`
object:
x <- 1:10
local({
x <- 11:20
x[3:5] <<- 13:15
})
x
#[1] 1 2 13 14 15 6 7 8 9 10
x <- 1:10
local({
x <- 11:20
x <<- `[<-`(x, 3:5, value=13:15)
})
x
# [1] 11 12 13 14 15 16 17 18 19 20
x <- 1:10
local({
x <- 11:20
`*tmp*` <- get("x", envir=parent.env(environment()), inherits=TRUE)
x <<- `[<-`(`*tmp*`, 3:5, value=13:15)
rm(`*tmp*`)
})
x
# [1] 1 2 13 14 15 6 7 8 9 10
Other examples could probably be found.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With