Skip to content

Instantly share code, notes, and snippets.

@moodymudskipper
Created June 15, 2021 21:23
Show Gist options
  • Save moodymudskipper/20f49cd4b8ec12b3f5a22121fdf4512b to your computer and use it in GitHub Desktop.
Save moodymudskipper/20f49cd4b8ec12b3f5a22121fdf4512b to your computer and use it in GitHub Desktop.
fake package
fake_package <- function(name, exported = NULL, unexported = NULL, attach = TRUE) {
# fetch and eval call to create `makeNamespace`
eval(body(loadNamespace)[[c(8, 4, 4)]])
# create an empty namespace
ns <- makeNamespace(name)
# makethis namespace the closure env of our input functions
exported <- lapply(exported, `environment<-`, ns)
unexported <- lapply(unexported, `environment<-`, ns)
# place these in the namespace
list2env(exported, ns)
list2env(unexported, ns)
# export relevant functions
namespaceExport(ns, names(exported))
if(attach) {
# copy exported funs to "package:pkg" envir of the search path
attach(exported, name = paste0("package:", name))
}
invisible()
}
fake_package(
"fake",
exported = list(add_2 = function(x) add_1(x) + 1),
unexported = list(add_1 = function(x) x + 1))
# the search path looks as it would after a library call
search()
#> [1] ".GlobalEnv" "package:fake" "package:stats"
#> [4] "package:graphics" "package:grDevices" "package:utils"
#> [7] "package:datasets" "package:methods" "Autoloads"
#> [10] "tools:callr" "package:base"
# add_2 was exported
add_2
#> function(x) add_1(x) + 1
#> <environment: namespace:fake>
fake::add_2
#> function(x) add_1(x) + 1
#> <environment: namespace:fake>
fake:::add_2
#> function(x) add_1(x) + 1
#> <environment: namespace:fake>
# add_1 was not, so as expected can't be found
add_1
#> Error: object 'add_1' not found
fake::add_1
#> Error: 'add_1' is not an exported object from 'namespace:fake'
fake:::add_1
#> function(x) x + 1
#> <environment: namespace:fake>
# let's try it
add_2(3)
#> [1] 5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment