Repository navigation
docs: the Known limitations section listed nothing that is still a limitation - #47
Merged
Merged
Conversation
…mitation
Every claim in it was obsolete, measured at v0.11.0 on 2026-10-04:
BEGIN { } listed as failing parses
END { } listed as failing parses
CRuby stdlib 46 of 47 47 of 47
the one refusal mkmf.rb parses
mkmf.rb tripped on `def self::log_open` -- the `def self::name` form -- which
parses now, and that is what took the stdlib figure to 47.
A section naming limitations that no longer exist is worse than a stale number:
a reader avoids BEGIN and END for nothing, or goes round a bug that is fixed.
The section was also dated "as of v0.4.0", seven minors back.
So the page's claims are now EXECUTABLE. TestReadmeClaimsStillHold parses each
construct the section names; TestUnderPermissiveNotOver pins the design claim
with its discriminating case (MRI refuses BEGIN inside a method body, and so
must this); TestCRubyStdlibTopLevelParses runs the sweep that produced the
47-of-47 figure, and SKIPS when no CRuby tree is present -- CI has none, which
is why the figure is stated as a dated local measurement rather than a gate.
Before writing "none", I probed 23 further constructs against `ruby -c` --
flip-flops, redo, __END__/DATA, heredoc-with-method-call, _1, it, endless
methods, rightward assignment, one-line pattern match, hash shorthand, all
three anonymous forwards, refinements, ?a, imaginary/rational literals -- and
found no gap and no over-acceptance. The section says that twenty-three
hand-picked constructs are not a completeness proof, because they are not.
Also in ast.go: the Lines doc said "all 55 node types" and the file defines 56.
A count of something the file itself defines rots on the next addition and says
nothing the reader needs, so it is gone rather than corrected -- I had reread
that comment the day before and not checked the number.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…t a literal
`alias / +` was refused with "expected a method name". MRI's grammar sets
EXPR_FNAME|EXPR_FITEM for the items of both alias and undef --
k_alias fitem {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem
k_undef undef_list
-- and the lexer's atMethodName listed only `def`, `.`, `&.` and `::`, so after
`alias` a `/` opened a regexp instead of naming the division method.
Only `/` was affected, because it is the one operator character that also opens
a literal in a value position: `alias + plus`, `alias [] at`, `alias <=> cmp`
and `alias :/ :+` all parsed already. The operator as the OLD name parsed too --
it is the NEW name that sits in the state the lexer got wrong.
This is how Pathname aliases its `/`, and CRuby's own pathname.rb line 358 is
that exact line.
HOW IT WAS FOUND, which is the part worth keeping. The stdlib sweep added one
commit earlier for the README was written to "skip when no CRuby is present",
on my assumption that CI has none. CI's runner carries Ruby **3.2**, not 4.0.5:
the test ran, swept 66 files instead of 47, and refused one. A sweep restricted
to the targeted version would have missed a construct that is valid in every
Ruby and that no 4.0.5 top-level file happens to use. The README now says the
sweep runs against whatever CRuby is on the machine, and why.
atMethodName's own comment already recorded this shape once -- "the previous
form named only `def`, so all four literal openers silently carried the wrong
rule after a dot". The alias/undef omission is the same omission a second time,
which is an argument for the predicate, not against it.
Controls, because a lexer state that leaks would turn every regexp into a
division: a regexp in an assignment and as an argument, division, a regexp
AFTER an `alias / +`, division after an `undef`, and a regexp after `undef /`.
All parse, and all are in the test.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
tannevaled
added a commit
to go-embedded-ruby/ruby
that referenced
this pull request
Oct 4, 2026
CRuby's pathname.rb writes `alias / +`. rbgo's prelude wrote
def /(other)
self + other
end
because the parser refused the alias: after `alias`, a `/` opened a regexp
instead of naming the division method. That is fixed in go-ruby-parser v0.11.1
(go-ruby-parser/parser#47), which this bumps to.
The workaround was not only a reflection difference. Three things diverged,
measured against ruby 4.0.5:
Pathname.instance_method(:/).original_name ruby :+ before :/
instance_method(:/) == instance_method(:+) ruby true before false
with #+ redefined, `Pathname.new("/a") / "b"`
ruby #<Pathname:/a/b>
before "HIJACKED"
The third is BEHAVIOUR: an alias keeps the body it was made from, while a
forwarding def follows whatever #+ later becomes. All three now match.
Measured: library/pathname/divide_spec.rb goes 0 -> 1, which is MRI's own
ceiling for it, and the spec is one example whose title is "is an alias of
Pathname#+" -- the corpus naming exactly this. The pathname library specs go
38 -> 39 overall with no file down. That suite is under library/, which the
ratchet does not sweep (only language/ and core/), so the gain is real but
ungated; nothing in language/ or core/ moves.
The prelude was the only site with this shape: a scan for an operator-named def
whose body just forwards to another operator found one, this one.
Closes nothing; enabled by go-ruby-parser/parser#47, which was itself found by
a README-claims test sweeping CI's Ruby 3.2 stdlib.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The Known limitations section listed nothing that is still a limitation.
Measured at v0.11.0 on 2026-10-04:
BEGIN { }— "does not parse"END { }— "does not parse"mkmf.rbmkmf.rbtripped ondef self::log_open— thedef self::nameform — whichparses now, and that is what took the stdlib figure to 47 of 47.
The section was also dated "as of v0.4.0", seven minors back.
Why this is worse than a stale number
A section naming limitations that no longer exist sends a reader round a bug
that is fixed: they avoid
BEGIN/ENDfor nothing, or go looking for themkmf.rbrefusal. A number that is merely out of date is read as approximate;a named limitation is read as a fact.
The claims are now executable
TestReadmeClaimsStillHoldparses every construct the section names, soa future change that breaks one fails the suite rather than quietly
contradicting the page.
TestUnderPermissiveNotOverpins the design claim with its discriminatingcase: MRI refuses
BEGINinside a method body, and so must this. A test thatonly checked things we accept could not tell under- from over-permissive.
TestCRubyStdlibTopLevelParsesruns the sweep that produced the 47-of-47figure, and skips when no CRuby tree is present. CI has none, which is
exactly why the README states that figure as a dated local measurement
rather than as a gate — with the command to reproduce it.
Before writing "none"
I probed 23 further constructs against
ruby -c— flip-flops,redo,__END__/DATA, heredoc-with-method-call,_1,it, endless methods,rightward assignment, one-line pattern match, hash shorthand, all three
anonymous forwards, refinements,
?a, imaginary/rational literals, specialglobals — and found no gap and no over-acceptance, including the one MRI
rejects.
The section says in as many words that twenty-three hand-picked constructs are
not a completeness proof, because they are not.
Also
ast.go'sLinesdoc said "a position field on all 55 node types" andthe file defines 56. A count of something the file itself defines rots on
the next addition and tells the reader nothing, so it is gone rather than
corrected — I had reread that comment the day before, while adding
Block.Line,and did not check the number.
Green
go test ./... -count=1exit 0 (4 packages),gofmtclean, and theparserpackage stays at 100.0% of statements.
🤖 Generated with Claude Code