I'm trying to figure why rlang::mut_node_car fails in some code I am working on.
I have a simple example of a quosue
q <- rlang::quo( a + b)
and I want to use mut_nod_car to change the '+' to a '-'
The code in this reprex works as expected
suppressPackageStartupMessages(library(tidyverse))
q <- rlang::quo(a + b)
# what q looks like to start with
q
#> <quosure: frame>
#> ~a + b
# note q is setup for addition
q
#> <quosure: frame>
#> ~a + b
a <- 2
b <- 3
# and evaluating it produces 5, as expected
rlang::eval_tidy(q)
#> [1] 5
## this works and changed + to -
change_to_minus <- function(q) {
#q2 <- q[[2]]
q2 <- rlang::f_rhs(q)
car <- rlang::node_car(q2)
cdr <- rlang::node_cdr(q2)
mod_car <- function(car) {
if (rlang::is_symbol(car)) {
if (car == rlang::sym("+")) {
rlang::mut_node_car(q2, rlang::sym("-"))
}
}
}
mod_car(car)
}
change_to_minus(q)
# note that the '+' is now a '-' as expected
q
#> <quosure: frame>
#> ~a - b
# and evaluating it produces -1, as expected
rlang::eval_tidy(q)
#> [1] -1
However this code fail so badly it can't be run in a reprex. Except for being
wrapped in a function is it is above it seems to me to be the same code.
why does this code fail????
q <- rlang::quo(a + b)
# what q looks like to start with
# this does not work, why ???
rhs <- rlang::f_rhs(q)
car <- rlang::node_car(rhs)
if (rlang::is_symbol(car)) {
rlang::mut_node_car(car, rlang::sym("-"))
}
# note that garbage has been inserted into q
# also because the rlang:node functions do
# not do any checking this result will eventually
# crash the R session because something, no
# doubt, has been corrupted
q
The check of q at the end produces
q
<quosure: global>
~a 0�� b
Note that the rlang::mut functions don't do any checking and will mindlessly write over any memory they happed to be pointed which is probably why the reprex fails. This code also corrupts the R Studio session it is running when a reprex isn't used
So why does the the code in the second example fails???
Thanks for any insights...
Dan