Skip to content

fix(abc): float and suffixed numeric operands score no condition in Ruby and Elixir #1379

Description

@dekobon

Summary

Found sweeping siblings for #1359 (grammar-dispatch §7). The
terminal-bool operand sets that ABC's unary-conditional walker consults
(src/macros/kind_sets.rs, Fitzpatrick Rule 9, #557) name Integer for
Ruby and Elixir but not the other numeric literal kinds those grammars
emit. A float or a suffixed numeric used as a bare && / || operand
scores one condition instead of two.

Python's set already names both Float and Integer, so the three
truthy-value languages disagree with each other for no reason anyone
recorded.

Reproduction

$ cat a.rb
def f
  a && 1
end
$ bca metrics --no-config -p a.rb   # abc.conditions: 2   (correct)

$ cat b.rb
def f
  a && 1.0
end
$ bca metrics --no-config -p b.rb   # abc.conditions: 1   (wrong)

a && 1r and a && 2i report 1 for the same reason. Elixir:

$ printf 'def f(a) do\n  a && 1\nend\n'    # abc.conditions: 2
$ printf 'def f(a) do\n  a && 1.0\nend\n'  # abc.conditions: 1

Python is the control and is already right:

$ printf 'def f(a):\n    return a and 1.0\n'   # abc.conditions: 2

Why the count drops rather than errors

src/metrics/abc/ruby.rs:111,134 requires the operand's kind to be in
ruby_bool_terminal_kinds!() and its parent list kind to be a
Binary*. A float / rational / complex operand is not in the set,
so the walker recurses one level, and the recursion then fails the
list-kind gate. Nothing warns; the condition is simply not counted.

Fix shape

src/macros/kind_sets.rs:

Then re-derive the comment above each macro, which currently enumerates
the operand kinds as a closed list and so is part of the contract.

Sweep

The remaining seventeen sets were checked. Lua, Tcl, iRules and the four
JS-family sets name a single Number kind that covers both integers and
floats, so they have no gap. C#, Java, Groovy, Rust, Go, C++, PHP,
Kotlin and Perl name no numeric literal at all — plausibly deliberate,
since a bare numeric is not a boolean operand in most of them, but no
comment says so and Perl at least is a truthy-value language. Worth
confirming Perl separately rather than assuming.

Tests

Per-language abc.conditions assertions for a float operand, plus the
Ruby suffixed forms. abc.conditions == cyclomatic() - 1 per space is
the cross-check .claude/rules/grammar-dispatch.md §8 asks for.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions