You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Range#min/#max with a comparison block say "unbounded" where MRI says "endless" and "beginless" — and no spec asserts either #854
min/max with a custom comparison block say "unbounded" where MRI says two different words
Measured on main:
$ rbgo -e 'begin; (1..).min { |a,b| a<=>b }; rescue => e; p e.message; end'"cannot get the minimum of unbounded range with custom comparison method"
MRI 4.0.9, range.c:
1649: rb_raise(rb_eRangeError, "cannot get the minimum of endless range with custom comparison method");
1762: rb_raise(rb_eRangeError, "cannot get the maximum of beginless range with custom comparison method");
So upstream uses opposite words for the two, and each is the end the method
actually needs: min with a block must walk from the beginning to the end, so
an endless range defeats it; max must walk back from the end, so a beginless one does. rbgo has a single format string with a %s for min/max
and the word unbounded for both:
// internal/vm/builtins.go:11903raise("RangeError", "cannot get the %s of unbounded range with custom comparison method", which)
unbounded is arguably the better word — it is true of both cases, where MRI's
pair reads as if someone wrote each message where they needed it. But this
project's standard is MRI's bytes, and the surrounding messages all match
exactly (cannot get the last element of endless range, cannot convert endless range to an array, and #853 adds cannot convert endless range to a set).
⛔ Why this is not a one-word fix, and why I have not done it
The two words are not interchangeable between the two methods, so a change
has to split the single format string and get the asymmetry the right way round.
And:
$ grep -rn "minimum of endless range\|minimum of unbounded range" core/(nothing)
No spec in language/ or core/ asserts either message, so nothing would
catch inverting them. A change with no test and an easy-to-invert asymmetry is
exactly the shape that lands backwards and stays that way.
What it needs, in order: a Go test pinning both messages against the two MRI
lines above (quoted, with their file and line), then the split. That is small but
it is its own change — I kept it out of #853, which is a hang fix measured
against a control, because mixing an unverifiable cosmetic edit into a crash fix
makes the whole thing harder to trust.
Found while auditing the endless-range family for #853: every other guard in it
matches MRI exactly, which is what made this one visible.
Activity