I've partialised the glue
function in a project I'm working on so that we can use agreed-on delimiters without having to tell glue about them all the time. But when we go to use the partialised function inside another function, it stops working:
library(purrr)
library(glue)
glue_query <- partial(glue, .open = "<<", .close = ">>")
# case 1: use partialised function in same scope
x <- 15
glue_query("There are <<x>> apples here!")
#> There are 15 apples here!
# case 2: use partialised function in different scope
myfunc_partialised <- function(y) {
glue_query("The thing I called y is actually <<y>>")
}
myfunc_partialised(15)
#> Error in eval(parse(text = text, keep.source = FALSE), envir): object 'y' not found
# case 3: use function directly
myfunc_regular <- function(z) {
glue("The thing I called z is actually <<z>>", .open = "<<", .close = ">>")
}
myfunc_regular(15)
#> The thing I called z is actually 15
Created on 2021-07-09 by the reprex package (v2.0.0)
I get the sense that glue_query
is looking for objects to interpolate in the environment it was defined in, rather than in the environment it's called in. Is that's what happening here? Can I direct it to use the calling environment? I'd like to use it throughout my package!
EDIT: I understand that glue
has an .envir
argument that controls which environment the expressions are evaluated in, but I'm not quite sure what to use to ensure it plays nice here!
It does seem that partial()
makes it much more difficult to get the correct environment. Instead you can write your own wrapper
glue_query <- function(..., .open = "<<", .close = ">>", .envir=parent.frame()) {
glue(..., .open=.open, .close=.close, .envir=.envir)
}
This will work with both the test cases you provided.