Remove source reference (see srcref
) recursively and in-place.
Please see 'Details' for side effects.
Details
When running under interactive mode (or "keep.source"
option is
TRUE
), R stores the source code that generate the function or
expression in an environment as an attribute. Normally the reference data
does not affect the results. However, when trying to compare or digest the
data, the source reference will be included in the serialization data,
resulting in different digests (see 'Examples').
It might be to remove the source data before comparing. One option is to
run the script non-interactively or set "keep.source"
to false.
Alternatively, we could remove this attributes from R objects. R functions
removeSource
removes source from function and language
objects recursively. However, this is far from enough when comparing or
generating hash for R objects, since a function
, pairlist
,
environment
, or list
may contains functions or expressions (
sometimes nested) that keeps source code.
Side Effects and Exceptions
remove_source
removes source reference recursively for most R objects.
Unlike removeSource
which returns a new object,
remove_source
alters the original R object, allowing elements in the
lists and environments to be modified without copying on write. However,
this side effect need to be used carefully, if the script depends on
extracting the source code. For example, deparse
with
control = "source"
will fail if source is removed.
remove_source
ignores the objects that come from namespace
(most likely package variables).
Examples
keep_source <- getOption("keep.source", TRUE)
options(keep.source = TRUE)
x <- function(){ a + 1L }
y <- function(){ a + 1L }
identical(x, y, ignore.srcref = FALSE) # FALSE
#> [1] FALSE
is.null(attr(x, "srcref")) # FALSE
#> [1] FALSE
# x is equal to y if we ignore the code generating them
identical(x, y, ignore.srcref = TRUE) # TRUE
#> [1] TRUE
# digest x and y
digest(x)
#> [1] "3eea1c95e870b241e78d9df50ad39182"
digest(y)
#> [1] "bb65dd5bef00f30a902975f832284cf4"
digest(x) == digest(y) # FALSE
#> [1] FALSE
remove_source(x)
remove_source(y)
identical(x, y) # TRUE
#> [1] TRUE
is.null(attr(x, "srcref")) # TRUE
#> [1] TRUE
digest(x) == digest(y) # TRUE
#> [1] TRUE
## Not example below
# reset this example options
options(keep.source = keep_source)