Use module
to define self contained organisational units. Modules have
their own search path. import
can be used to import packages.
use
can be used to import other modules. Use export
to define
which objects to export. expose
can be used to reuse function
definitions from another module.
export(..., where = parent.frame())expose(module, ..., reInit = TRUE, where = parent.frame())
extend(module, with)
import(from, ..., attach = TRUE, where = parent.frame())
module(expr = { }, topEncl = autoTopEncl(envir), envir = parent.frame())
autoTopEncl(where)
use(module, ..., attach = FALSE, reInit = TRUE, where = parent.frame())
(character, or unquoted expression) names to import from package or names to export from module. For exports a character of length 1 with a leading "^" is interpreted as regular expression.
(environment) typically the calling environment. Should only be relevant for testing.
(character | module) a module as file or folder name or a list representing a module.
(logical) whether to re-initialize module. This is only relevant if a module has state which can be changed. This argument is passed to as.module.
(character, or unquoted expression) a package name
(logical) whether to attach the module to the search path
an expression
(environment) the root of the local search path. It is tried to find a good default via autoTopEncl.
(environment) the environment from where module
is
called. Used to determine the top level environment and should not be
supplied by the use.
topEncl
is the environment where the search of the module ends.
autoTopEncl
handles the different situations. In general it defaults
to the base environment or the environment from which module
has been
called. If you are using use
or expose
referring to a module in
a file, it will always be the base environment. When
identical(topenv(parent.frame()), globalenv())
is false it (most
likely) means that the module is part of a package. In that case the module
defines a sub unit within a package but has access to the packages namespace.
This is relevant when you use the function module explicitly. When you define
a nested module the search path connects to the environment of the enclosing
module.
import
and use
can replace library and attach.
However they behave differently and are only designed to be used within
modules. Both will work when called in the .GlobalEnv
but should only
be used for development and debugging of modules.
export
will never export a function with a leading "." in its name.
expose
is similar to use
but instead of attaching a module it
will copy all elements into the calling environment. This means that
exposed functions can be (re-)exported.
extend
can be used to extend an existing module definition. This
feature is meant to be used by a module author. This can be very useful to
write unit tests when they need to have access to private member functions
of the module. It is not safe as a consumer or user of a module to use this
feature as it breaks encapsulation. When you are looking for mechanisms for
reuse, expose
and use
should be favoured.
# NOT RUN {
vignette("modulesInR", "modules")
# }
# NOT RUN {
m <- module({
fun <- function(x) x
})
m$fun(1)
m <- module({
import("stats", "median")
export("fun")
fun <- function(x) {
## This is an identity function
## x (ANY)
x
}
})
m$fun
m
# }
Run the code above in your browser using DataLab