0.5.0 - 2026-07-16
Release Notes
Driven by the ranks-301-500 audit (ry 0.4.0 on the top-500 CRAN packages).
Minor bump: RY050's dispatch semantics, RY097's collapse criteria, and the
new binding/quoting/narrowing rules intentionally change reported
diagnostics between versions.
Performance
- Pipe-chain inference was exponential: each
%>%/|>stage re-inferred
its entire left-hand side inside the desugared call, so a 20-stage chain
took ~14 s and longer chains never finished. The inferred LHS type is
now reused. gt (289 R files, previously unscannable) checks in ~2.4 s. - The required-parameter force-flow analysis walked each
ifbranch twice
(once for "forces", once for "falls through"), which is exponential on
longelse ifdispatcher chains. Both facts are now computed in one
pass. lavaan and stargazer (previously >60 min, never completed) check
in ~2.3 s and ~0.8 s.
Fixed
assign("name", value, envir = ...),makeActiveBinding(), and
delayedAssign()with a literal name now create package-level bindings
(any nesting depth underR/). Removes whole-package RY010 cascades in
clock (204 -> 0), rJava, otel, parallelly, and others..packageName
is bound in every package namespace.- A string-literal assignment target (
"Math.foo" <- function(...)) now
binds, aliases, and establishes S3 dispatch context (.Generic,
.Method) exactly like an identifier target (chron 35 -> 10). alist()arguments are quoted, never resolved as variables, and the
call returns a list (Deriv 111 -> 8, ade4 RY010 42 -> 2).- A union whose members are all functions is callable; RY070 no longer
fires onf <- if (p) function(...) ... else function(...)followed by
f(...). Argument checks report only findings that hold for every
member signature. NULL/function unions still report RY070. - RY097 (not-R-source) now also collapses files that mostly parse as R
but are riddled with parse errors (>= 5 errors and >= 15% of top-level
statements): Ratfor, GAUSS, and markdown-table files underinst/
(pacman 270 -> 27, plm 136 -> 36 total). is.list()/is.function()/is.environment()/is.data.frame()guards
narrow a parameter whose type came only from its default, so
f <- function(x = FALSE) if (is.list(x)) x$fieldno longer reports
RY061 (visNetwork 34 -> 5 RY061).- Assignments nested inside call arguments of
if/whileconditions
(if (grepl(p, ti <- text[i]))) now bind in the enclosing scope
(litedown 27 -> 10). - RY033's message no longer claims R compares "byte values"; R coerces
the numeric operand to character and compares lexicographically. - The typeshed ships registered-but-unexported base S3 methods (e.g.
stats:::print.anova), so RY050 no longer reports them missing
(spatial, Cairo). RY050 also honors<generic>.defaultas a valid
dispatch fallback:coef(glm_fit)no longer reports a missing
coef.glm. Consequently RY050 can no longer fire for generics that
have a.defaultmethod (such asprint) — dispatch always succeeds
for them.
Removed
RY095(negation-comparison-precedence) is retired. The rule assumed C
operator precedence, but R gives unary!lower precedence than
comparison operators:!x == yparses as!(x == y), so every flagged
site was correct code and the suggested rewrite was a semantic no-op.
The rule number will not be reused.
Fixed
RY096no longer fires in functions whose formals include...:
there,hasArg(name)legitimately tests for a dots-supplied argument
(if (hasArg(b)) list(...)$b). All 84 corpus hits were this idiom.
The rule now only flags the provable case — ahasArg()naming a
non-formal in a function without...is alwaysFALSE.
Corrections to 0.4.0 release notes
- The scales
!length(x) == 1guards cited as newly found bugs were not
bugs; they parse aslength(x) != 1and behave as intended. The same
applies to RY095 reports in rpart, mice, quantreg, spdep, and mlflow.
Install ry-cli 0.5.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/sims1253/ry/releases/download/v0.5.0/ry-cli-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/sims1253/ry/releases/download/v0.5.0/ry-cli-installer.ps1 | iex"Download ry-cli 0.5.0
| File | Platform | Checksum |
|---|---|---|
| ry-cli-aarch64-apple-darwin.tar.gz | Apple Silicon macOS | checksum |
| ry-cli-x86_64-apple-darwin.tar.gz | Intel macOS | checksum |
| ry-cli-aarch64-pc-windows-msvc.zip | ARM64 Windows | checksum |
| ry-cli-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| ry-cli-aarch64-unknown-linux-gnu.tar.gz | ARM64 Linux | checksum |
| ry-cli-x86_64-unknown-linux-gnu.tar.gz | x64 Linux | checksum |