Skip to content

Commit aa293ec

Browse files
committed
Raise NameError instead of SyntaxError when Regexp-related read-only global variables are assigned
1 parent e2a94c7 commit aa293ec

File tree

2 files changed

+40
-8
lines changed

2 files changed

+40
-8
lines changed

spec/ruby/language/predefined_spec.rb

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,13 @@ def obj.foo2(&proc); proc.call; end
142142
eval %q{$& = ""}
143143
}.should raise_error(SyntaxError, /Can't set variable \$&/)
144144
end
145+
146+
it "is read-only when aliased" do
147+
alias $predefined_spec_ampersand $&
148+
-> {
149+
$predefined_spec_ampersand = ""
150+
}.should raise_error(NameError, '$predefined_spec_ampersand is a read-only variable')
151+
end
145152
end
146153

147154
describe "Predefined global $`" do
@@ -166,6 +173,13 @@ def obj.foo2(&proc); proc.call; end
166173
eval %q{$` = ""}
167174
}.should raise_error(SyntaxError, /Can't set variable \$`/)
168175
end
176+
177+
it "is read-only when aliased" do
178+
alias $predefined_spec_backquote $`
179+
-> {
180+
$predefined_spec_backquote = ""
181+
}.should raise_error(NameError, '$predefined_spec_backquote is a read-only variable')
182+
end
169183
end
170184

171185
describe "Predefined global $'" do
@@ -190,6 +204,13 @@ def obj.foo2(&proc); proc.call; end
190204
eval %q{$' = ""}
191205
}.should raise_error(SyntaxError, /Can't set variable \$'/)
192206
end
207+
208+
it "is read-only when aliased" do
209+
alias $predefined_spec_single_quote $'
210+
-> {
211+
$predefined_spec_single_quote = ""
212+
}.should raise_error(NameError, '$predefined_spec_single_quote is a read-only variable')
213+
end
193214
end
194215

195216
describe "Predefined global $+" do
@@ -214,6 +235,13 @@ def obj.foo2(&proc); proc.call; end
214235
eval %q{$+ = ""}
215236
}.should raise_error(SyntaxError, /Can't set variable \$\+/)
216237
end
238+
239+
it "is read-only when aliased" do
240+
alias $predefined_spec_plus $+
241+
-> {
242+
$predefined_spec_plus = ""
243+
}.should raise_error(NameError, '$predefined_spec_plus is a read-only variable')
244+
end
217245
end
218246

219247
describe "Predefined globals $1..N" do
@@ -1198,7 +1226,7 @@ def obj.foo2; yield; end
11981226
end
11991227

12001228
it "raises a SyntaxError if assigned to" do
1201-
-> { eval("nil = true") }.should raise_error(SyntaxError)
1229+
-> { eval("nil = true") }.should raise_error(SyntaxError, /Can't assign to nil/)
12021230
end
12031231
end
12041232

@@ -1208,7 +1236,7 @@ def obj.foo2; yield; end
12081236
end
12091237

12101238
it "raises a SyntaxError if assigned to" do
1211-
-> { eval("true = false") }.should raise_error(SyntaxError)
1239+
-> { eval("true = false") }.should raise_error(SyntaxError, /Can't assign to true/)
12121240
end
12131241
end
12141242

@@ -1218,13 +1246,13 @@ def obj.foo2; yield; end
12181246
end
12191247

12201248
it "raises a SyntaxError if assigned to" do
1221-
-> { eval("false = nil") }.should raise_error(SyntaxError)
1249+
-> { eval("false = nil") }.should raise_error(SyntaxError, /Can't assign to false/)
12221250
end
12231251
end
12241252

12251253
describe "The self pseudo-variable" do
12261254
it "raises a SyntaxError if assigned to" do
1227-
-> { eval("self = 1") }.should raise_error(SyntaxError)
1255+
-> { eval("self = 1") }.should raise_error(SyntaxError, /Can't change the value of self/)
12281256
end
12291257
end
12301258

src/main/ruby/truffleruby/core/match_data.rb

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,30 +188,34 @@ def backref_from_arg(index)
188188
-> s { Primitive.regexp_last_match_get(s) },
189189
Truffle::RegexpOperations::LAST_MATCH_SET)
190190

191+
# Prism gives a SyntaxError if $` is not aliased
191192
Truffle::KernelOperations.define_hooked_variable(
192193
:'$`',
193194
-> s { match = Primitive.regexp_last_match_get(s)
194195
match.pre_match if match },
195-
-> { raise SyntaxError, "Can't set variable $`" },
196+
-> name, _ { raise NameError, "#{name} is a read-only variable" },
196197
-> s { 'global-variable' if Primitive.regexp_last_match_get(s) })
197198

199+
# Prism gives a SyntaxError if $' is not aliased
198200
Truffle::KernelOperations.define_hooked_variable(
199201
:"$'",
200202
-> s { match = Primitive.regexp_last_match_get(s)
201203
match.post_match if match },
202-
-> { raise SyntaxError, "Can't set variable $'" },
204+
-> name, _ { raise NameError, "#{name} is a read-only variable" },
203205
-> s { 'global-variable' if Primitive.regexp_last_match_get(s) })
204206

207+
# Prism gives a SyntaxError if $& is not aliased
205208
Truffle::KernelOperations.define_hooked_variable(
206209
:'$&',
207210
-> s { match = Primitive.regexp_last_match_get(s)
208211
match[0] if match },
209-
-> { raise SyntaxError, "Can't set variable $&" },
212+
-> name, _ { raise NameError, "#{name} is a read-only variable" },
210213
-> s { 'global-variable' if Primitive.regexp_last_match_get(s) })
211214

215+
# Prism gives a SyntaxError if $+ is not aliased
212216
Truffle::KernelOperations.define_hooked_variable(
213217
:'$+',
214218
-> s { match = Primitive.regexp_last_match_get(s)
215219
match.captures.reverse.find { |m| !Primitive.nil?(m) } if match },
216-
-> { raise SyntaxError, "Can't set variable $+" },
220+
-> name, _ { raise NameError, "#{name} is a read-only variable" },
217221
-> s { 'global-variable' if Primitive.regexp_last_match_get(s) })

0 commit comments

Comments
 (0)