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
a non-ASCII uppercase letter must start a CONSTANT, not a local variable #57
A name beginning with a non-ASCII uppercase letter is a constant in Ruby.
The parser classifies it as an ordinary identifier, so the assignment creates a
local variable and no constant exists afterwards.
Measured against /usr/bin/ruby (2.6.10) and rbgo built from go-embedded-ruby/ruby@main, same source both times:
Ἅ is U+1F0D, GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA — an uppercase
letter outside ASCII. The lowercase side is already right: μ = 1 is a local
variable on both engines, and defined? agrees.
The rule
MRI's lexer decides constant-ness from the first character's CASE, not from its
being in A-Z. parse.y reaches tCONSTANT for any identifier whose first
character is uppercase, and for a multibyte character that question is answered
by the encoding's case table rather than by a byte range — which is why ἍBB is a constant and μm is not.
Why it surfaced
ruby/spec's language/variables_spec.rb:885:
it'parses a non-ASCII upcased character as a constant identifier'do->{eval("def test\n ἍBB = 1\nend")}.should.raise(SyntaxError,/dynamic constant assignment/)end
The example needs two things that are missing in two different places: this
classification, and a dynamic constant assignment check in
go-embedded-ruby/ruby's compiler (filed there). Fixing either one alone leaves
the example failing, so this is not blocked on that one and that one is not
blocked on this.
Scope note
The companion question — which characters count as uppercase for an identifier
start — is worth settling from Ruby's own table rather than from Go's unicode.IsUpper, since the two need not agree on titlecase characters
(Dž/dž/DŽ) or on letters with no case at all (CJK, Hebrew, Arabic), and an
identifier starting with a caseless letter is a LOCAL variable in Ruby, not a
constant. A test over one character from each of those three groups would pin it.
Activity