Unpack a package call into a self-contained, self-verifying replay script
Source:R/unpack_call.R
unpack_call.RdRuns the call once, captures its inputs and result, extracts the source of the executed function and its same-package helpers, and writes a replay project:
Arguments
- expr
An unevaluated function call, written as you would normally run it, e.g.
predict(fit, newdata = recent_data)orstats::fivenum(x). For S3 generics the dispatch argument can be evaluated once to determine the method, controlled byeval_dispatch.- output_dir
Directory to create the replay project in.
- max_depth
Maximum depth to follow same-package internal helpers.
- overwrite
Overwrite an existing non-empty
output_dir?- dispatch
How unresolved internal S3 dispatch is handled. The default,
"candidates", extracts package-internal candidate methods for runtime dispatch;"static"retains static-only extraction.- eval_dispatch
Should a computed (call-shaped) dispatch argument be evaluated once to resolve the S3/S4 method? The default
TRUEgives accurate method resolution but executes that piece of your code; the printed output says so whenever it happens. SetFALSEto leave computed dispatch unresolved and analyze the generic itself. Bare symbols are still inspected to resolve dispatch and may force a promise binding; literals are inspected directly.- on_error
How a call that raises an error is handled. The default,
"capture", still writes a replay project: it records the error (class, message, parent condition) and inputs forced before the failure, andreplay.Rverifies by asserting the replayed call reproduces an equivalent error (matching primary condition class and normalized message, or domain-specific regex/predicate) rather than comparing a result value."propagate"restores the pre-failure-capture behavior: the error surfaces immediately and no replay project is written.- error_pattern
Optional regular expression to match against the error message during replay failure verification.
- error_predicate
Optional custom predicate function
function(e)returningTRUEwhenerepresents an equivalent failure condition.- store
An optional
insider_storehandle (seeinsider_store()). When supplied, the returned object is also recorded in the store viastore_save(); the resulting id is attached as its"store_id"attribute. The default,NULL, records nothing, consistent with the store's explicit, opt-in design.- store_label
An optional label passed through to
store_save()whenstoreis supplied.Optional character tags passed through to
store_save()whenstoreis supplied.
Details
output_dir/
replay.R self-contained script: documented functions,
input loading, the reproducing call, and a
verification block
customize.R hand-editable copy of the extracted function sources
compare.R placeholder comparison script using customize.R
data/*.rds captured inputs and the original result
insider_manifest.rds machine-readable unpack metadataRunning source("replay.R") from output_dir re-executes the call using
the extracted functions and checks the result against the stored original
(and, when the package is installed, against a live package call). The
script header records provenance (package, version, source repository) and
the findings of a static security scan of the extracted code.
Hidden state the resolved target silently depends on is captured before its
invocation and stored in data/hidden_state.rds. When method dispatch
evaluates a computed argument, the snapshot includes those effects because
replay loads the captured dispatch value instead of evaluating it again.
Behavior-changing options (contrasts, na.action) are always captured and
restored by the script; the RNG state (RNGkind() and .Random.seed) is
captured and restored when the extracted call path uses random-number
functions. The script header lists what was restored, what is reported only
(locale, timezone), and what could not be captured.
Examples
x <- c(1, 3, 5, 7, 100)
dir <- file.path(tempdir(), "fivenum_replay")
unpack_call(stats::fivenum(x), output_dir = dir, overwrite = TRUE)
#>
#> ── insideR unpack ──────────────────────────────────────────────────────────────
#> Call: `stats::fivenum(x = x)`
#> Replay project written to /tmp/RtmpJqZdjB/fivenum_replay
#> • Script: /tmp/RtmpJqZdjB/fivenum_replay/replay.R
#> • Extracted function: `fivenum()`
#> • Captured input: "x"
#> • Replay status: full
#> • Security scan: no risky calls detected
#> Run it with: `setwd("/tmp/RtmpJqZdjB/fivenum_replay"); source("replay.R")`