bs_dependency_defer() factory-built closures collide on the memoise cache
Nobody has claimed this yet.
- Dominant language
- SCSS
- Stars
- 569
- Forks
- 72
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 5
Description
bs_dependency_defer(func) memoises func against a shared cache keyed on formals(f) + body(f) + call args. Closures produced by a factory (the pattern from the "Dynamically themeable component" vignette) only differ in captured variables, so they all hash to the same key and every dependency after the first is served the first one's compiled output.
library(bslib)
mk_dep <- function(name, css) {
bs_dependency_defer(function(theme) {
if (!is_bs_theme(theme)) theme <- bs_theme(version = 5)
tmp <- tempfile(fileext = ".scss"); writeLines(css, tmp)
bs_dependency(input = sass::sass_file(tmp), theme = theme,
name = paste0("test-", name), version = "0.0.0")
})
}
mk_dep("red", ".x{color:red}")()$name
mk_dep("blue", ".x{color:blue}")()$name
#> [1] "test-red"
#> [1] "test-red" # expected "test-blue"
Today's viable workarounds are either memoise = FALSE or the one-liner in the docs suggestion below.
Suggested fixes:
- Code: add an optional cache_key to bs_dependency_defer() folded into the memoise key: bs_dependency_defer(func, memoise = TRUE, cache_key = NULL) . Callers pass a stable per-component id and the collision is gone. Happy to PR.
- Docs: update the "Dynamically themeable component" vignette + ?bs_dependency_defer to warn about the shared-cache collision when func is factory-built, and show the caller-side one-liner, give the sole theme formal a per-component default so formals(f) differs per component:
build <- function(theme) { ... }
formals(build)$theme <- "unique-per-component-id"
bs_dependency_defer(build)
Happy to PR either.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the bs_dependency_defer() entry point and reproduce the collision with the provided R factory example. Inspect how the memoise key is built from the closure, then review ?bs_dependency_defer and the “Dynamically themeable component” vignette. Done means factory-built dependencies no longer return the first component’s result, or the documented workaround clearly prevents the collision.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- r, sass
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 62/100