unused_object
What it does
Detects objects that are defined (i.e. assigned a value) but never used.
Why is this bad?
Unused assignments are usually a sign of dead code or a bug. Removing them reduces noise.
Features
Apart from the standard usage of objects in R (e.g. x <- 1; print(x)), this rule handles the following cases:
String interpolation in the
glue,cli, andstringrpackages, e.g. in this casexis not reported as unused:x <- 1 glue::glue("{print(x)}")Custom functions or functions from other packages providing string interpolation are not supported.
The
%<>%operator frommagrittris supported.Explicit cross-file analysis: calls to
source()ortargets::tar_source()are detected, e.g. this doesn’t reportxas unused:foo.R:x <- 1 source("bar.R")bar.R:print(x)
Similarly, the definition could be made in the sourced file (
bar.R) and the use could be made in the other file (foo.R).Implicit cross-file analysis. All files in an
Rfolder (whether this corresponds to an R package or to another project type) are collated and share the same namespace, meaning that an object defined inR/a.Rcould seamlessly be detected as used inR/b.R.Some functions that can call other quoted functions (e.g.
do.call()) are supported.Assignments passed directly to a
testthatexpectation that runs its argument for the condition it signals (expect_error(),expect_warning(),expect_message(),expect_silent(),expect_defunct(),expect_deprecated(),expect_snapshot(),expect_no_condition(),expect_no_warning(),expect_no_error(),expect_no_message()) are not reported:expect_error(x <- foo)
You can provide a list of functions whose arguments can be assignments that shouldn’t be reported in jarl.toml.
Limitations
Some cases are deliberately left aside or might be tackled in the future:
Some functions such as
get()ormget()are not handled.Quoted code that is evaluated later may lead to false positives, e.g. this would wrongly report
xas unused:x <- 1 e <- quote(x + 1) eval(e)source()and alike only accept literal paths, not R objects, e.g. this isn’t handled by Jarl:for (i in my_paths) source(i)
In R Markdown and Quarto files
Jarl bundles all chunks together before running the analysis, meaning that unused_object would properly detect whether an object created in a chunk is used in another.
There are two other cases to handle:
objects that are present in a chunk with
eval = FALSEor#| eval: falseare not marked as “used”. For instance, in the following example, the objectxwould be reported as unused:```{r} x <- 1 ``` ```{r eval = FALSE} print(x) ```Note that if the option value is only available at runtime (e.g.
eval = my_r_object) then Jarl assumes that the chunk is evaluated.inline R code is taken into account,
`r x`in the text would keepxfrom being reported as unused.
In roxygen examples
R code in @examples and @examplesIf sections is checked too, in files under R/ in a package. This can be turned off with check-roxygen.
Examples
x <- 1 # unused
print(y)