I expect withr functions to have no side-effects, but was just surprised by this behavior. If I use withr::local_package("somepackage") inside of a function, after I call this function the package is not attached in the global environment even if it was before:
packageVersion("withr")
#> [1] '3.0.0'
# load dplyr in the global environment
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
# this works
mutate(mtcars, mpg = 2*mpg) |> head(1)
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> Mazda RX4 42 6 160 110 3.9 2.62 16.46 0 1 4 4
# use withr::local_package() to load dplyr in a function
f <- function() {
withr::local_package("dplyr")
print("dplyr is loaded in f() via withr::local_package()")
}
# run the function
f()
#> [1] "dplyr is loaded in f() via withr::local_package()"
# this does not work - dplyr was detached
mutate(mtcars, mpg = 2 * mpg) |> head(1)
#> Error in mutate(mtcars, mpg = 2 * mpg): could not find function "mutate"
In contrast, nearly the same code with withr::with_package does not have this problem:
packageVersion("withr")
#> [1] '3.0.0'
# load dplyr in the global environment
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
# this works
mutate(mtcars, mpg = 2*mpg) |> head(1)
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> Mazda RX4 42 6 160 110 3.9 2.62 16.46 0 1 4 4
# use withr::local_package() to load dplyr in a function
f <- function() {
withr::with_package("dplyr", {
print("dplyr is loaded in f() via withr::with_package()")
})
}
# run the function
f()
#> [1] "dplyr is loaded in f() via withr::local_package()"
# no problem:
mutate(mtcars, mpg = 2 * mpg) |> head(1)
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> Mazda RX4 42 6 160 110 3.9 2.62 16.46 0 1 4 4
I expect withr functions to have no side-effects, but was just surprised by this behavior. If I use withr::local_package("somepackage") inside of a function, after I call this function the package is not attached in the global environment even if it was before:
Created on 2024-06-11 with reprex v2.1.0
In contrast, nearly the same code with withr::with_package does not have this problem:
Created on 2024-06-11 with reprex v2.1.0