knitr::opts_chunk$set( collapse = TRUE, comment = "#>", error = TRUE # TODO: fix failing chunks )
This vignette summarizes how the internals of boomer work.
An important principle of {boomer} is that we don't modify the body of the function we rig.
rigged_file_ext <- boomer::rig(tools::file_ext) tools::file_ext rigged_file_ext
Instead we copy the original function but give it a new environment. This new environment is a child of the original environment, and is populated with shims of the functions called by the original function. We call this environment the mask.
# the original environment environment(tools::file_ext) # our new environment env <- environment(rigged_file_ext) env # its parent parent.env(env) # its content ls(env)
rig_impl()
does this job and is the main function of the package.
It calls wrap()
, the other important function, whose mission is to build verbose shims of functions
used in the rigged function. Both are detailed thereafter.
boom()
and rig()
boom()
is a wrapper around rig_impl()
, it rigs the calling function and runs the call,
it also has some hacky code so we can pipe to boom()
with {magrittr} (The hack is
not needed for the base pipe)
rig_impl()
Here's the diagram of dependencies of rig_impl()
flow::flow_view_deps(boomer:::rig_impl, show_imports = "packages")
rig_impl()
:
::
and :::
so when we find pkg::fun
or pkg:::fun
in the original function we don't wrap their output and not the ::
or :::
operator<-
and =
so functions created in the original function,
and thus impossible to shim at "rig time", can be made verbose too.wrap()
..FIRST_CALL..
and ..EVALED_ARGS..
in this environment,
..FIRST_CALL..
is a boolean initiated to TRUE
and set to FALSE
once the first
wrapper call is triggered, ..EVALED_ARGS..
is a named logical vector that keeps track of which
arguments have been evaled.wrap()
wrap()
builds verbose wrapper functions.
Its main aim is to print information directly related to the wrapped function (e.g. argument values and execution time).
However it does a couple more things:
..FIRST_CALL..
special variable introduced in above section.rig_in_namespace()
rig_in_namespace()
calls rig_impl()
on its inputs but unlike rig()
we want
the rigged functions to be bound in the namespace instead of the original functions.
To do this we unlock the namespace and assigned rigged functions there.
Since rig_in_namespace()
accepts several functions as arguments, and that they might
call each other, we also make sure we include wrapped versions of our rigged functions
in all the masks.
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.