The following issues are linted by default by this linter (see arguments for which can be de-activated optionally):
Usage
paste_linter(
allow_empty_sep = FALSE,
allow_to_string = FALSE,
allow_file_path = c("double_slash", "always", "never")
)
Arguments
- allow_empty_sep
Logical, default
FALSE
. IfTRUE
, usage ofpaste()
withsep = ""
is not linted.- allow_to_string
Logical, default
FALSE
. IfTRUE
, usage ofpaste()
andpaste0()
withcollapse = ", "
is not linted.- allow_file_path
String, one of
"never"
,"double_slash"
, or"always"
;"double_slash"
by default. If"never"
, usage ofpaste()
andpaste0()
to construct file paths is not linted. If"double_slash"
, strings containing consecutive forward slashes will not lint. The main use case here is for URLs -- "paths" like"https://"
will not induce lints, since constructing them withfile.path()
might be deemed unnatural. Lastly, if"always"
, strings with consecutive forward slashes will also lint. Note that"//"
is never linted when it comes at the beginning or end of the input, to avoid requiring empty inputs likefile.path("", ...)
orfile.path(..., "")
.
Details
Block usage of
paste()
withsep = ""
.paste0()
is a faster, more concise alternative.Block usage of
paste()
orpaste0()
withcollapse = ", "
.toString()
is a direct wrapper for this, and alternatives likeglue::glue_collapse()
might give better messages for humans.Block usage of
paste0()
that suppliessep=
-- this is not a formal argument topaste0
, and is likely to be a mistake.Block usage of
paste()
/paste0()
combined withrep()
that could be replaced bystrrep()
.strrep()
can handle the task of building a block of repeated strings (e.g. often used to build "horizontal lines" for messages). This is both more readable and skips the (likely small) overhead of putting two strings into the global string cache when only one is needed.Only target scalar usages --
strrep
can handle more complicated cases (e.g.strrep(letters, 26:1)
, but those aren't as easily translated from apaste(collapse=)
call.
See also
linters for a complete list of linters available in lintr.
Examples
# will produce lints
lint(
text = 'paste("a", "b", sep = "")',
linters = paste_linter()
)
#> ::warning file=<text>,line=1,col=1::file=<text>,line=1,col=1,[paste_linter] paste0(...) is better than paste(..., sep = "").
lint(
text = 'paste(c("a", "b"), collapse = ", ")',
linters = paste_linter()
)
#> ::warning file=<text>,line=1,col=1::file=<text>,line=1,col=1,[paste_linter] toString(.) is more expressive than paste(., collapse = ", "). Note also glue::glue_collapse() and and::and() for constructing human-readable / translation-friendly lists
lint(
text = 'paste0(c("a", "b"), sep = " ")',
linters = paste_linter()
)
#> ::warning file=<text>,line=1,col=1::file=<text>,line=1,col=1,[paste_linter] sep= is not a formal argument to paste0(); did you mean to use paste(), or collapse=?
lint(
text = 'paste0(rep("*", 10L), collapse = "")',
linters = paste_linter()
)
#> ::warning file=<text>,line=1,col=1::file=<text>,line=1,col=1,[paste_linter] strrep(x, times) is better than paste0(rep(x, times), collapse = "").
lint(
text = 'paste0("http://site.com/", path)',
linters = paste_linter(allow_file_path = "never")
)
#> ::warning file=<text>,line=1,col=1::file=<text>,line=1,col=1,[paste_linter] Construct file paths with file.path(...) instead of paste0(x, "/", y, "/", z). Note that paste() converts empty inputs to "", whereas file.path() leaves it empty.
# okay
lint(
text = 'paste0("a", "b")',
linters = paste_linter()
)
lint(
text = 'paste("a", "b", sep = "")',
linters = paste_linter(allow_empty_sep = TRUE)
)
lint(
text = 'toString(c("a", "b"))',
linters = paste_linter()
)
lint(
text = 'paste(c("a", "b"), collapse = ", ")',
linters = paste_linter(allow_to_string = TRUE)
)
lint(
text = 'paste(c("a", "b"))',
linters = paste_linter()
)
lint(
text = 'strrep("*", 10L)',
linters = paste_linter()
)
lint(
text = 'paste0(year, "/", month, "/", day)',
linters = paste_linter(allow_file_path = "always")
)
lint(
text = 'paste0("http://site.com/", path)',
linters = paste_linter()
)