Skip to content

0.5.0 - 2026-07-16

Choose a tag to compare

@github-actions github-actions released this 15 Jul 23:28

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 if branch twice
    (once for "forces", once for "falls through"), which is exponential on
    long else if dispatcher 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 under R/). 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 on f <- 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 under inst/
    (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$field no longer reports
    RY061 (visNetwork 34 -> 5 RY061).
  • Assignments nested inside call arguments of if/while conditions
    (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>.default as 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 .default method (such as print) — 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 == y parses 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

  • RY096 no 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 — a hasArg() naming a
    non-formal in a function without ... is always FALSE.

Corrections to 0.4.0 release notes

  • The scales !length(x) == 1 guards cited as newly found bugs were not
    bugs; they parse as length(x) != 1 and 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 | sh

Install 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