Skip to content

Commit c09a9ce

Browse files
committed
Improve specs of the for loop regarding variable scopes
1 parent 24b0501 commit c09a9ce

1 file changed

Lines changed: 100 additions & 2 deletions

File tree

language/for_spec.rb

Lines changed: 100 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,22 +215,120 @@ def each
215215
j.should == 6
216216
end
217217

218-
it "executes code in containing variable scope" do
218+
it "declares iteration variables in the surrounding variable scope" do
219+
for a, b in [[1,2]]
220+
end
221+
222+
a.should == 1
223+
b.should == 2
224+
end
225+
226+
it "declares variables in the body in the surrounding variable scope" do
219227
for i in 1..2
220228
a = 123
221229
end
222230

223231
a.should == 123
224232
end
225233

226-
it "executes code in containing variable scope with 'do'" do
234+
it "declares variables in the body in the surrounding variable scope with 'do'" do
227235
for i in 1..2 do
228236
a = 123
229237
end
230238

231239
a.should == 123
232240
end
233241

242+
it "declares variables inside a block as normal" do
243+
for i in 1..2 do
244+
proc {
245+
inside_proc = 42
246+
}.call
247+
end
248+
local_variables.should == [:i]
249+
end
250+
251+
it "declares variables inside a lambda as normal" do
252+
for i in 1..2 do
253+
-> {
254+
inside_proc = 42
255+
}.call
256+
end
257+
local_variables.should == [:i]
258+
end
259+
260+
it "can be nested" do
261+
for a in [6]
262+
for b in [7]
263+
c = a * b
264+
end
265+
end
266+
local_variables.sort.should == [:a, :b, :c]
267+
c.should == 42
268+
end
269+
270+
it "can be nested with blocks in between" do
271+
# This is an edge case spec for Ruby implementations which have
272+
# their own runtime scope per for loop body (like YARV and TruffleRuby)
273+
for a in [1]
274+
a1 = a
275+
a1.should == a
276+
for b in [2]
277+
b1 = b
278+
a1.should == a
279+
b1.should == b
280+
proc {
281+
inside_proc = 42
282+
283+
a1.should == a
284+
b1.should == b
285+
inside_proc.should == 42
286+
287+
for c in [3].map { |enum_var|
288+
a1.should == a
289+
b1.should == b
290+
inside_proc.should == 42
291+
enum_var
292+
}
293+
c1 = c
294+
295+
a1.should == a
296+
b1.should == b
297+
c1.should == c
298+
inside_proc.should == 42
299+
300+
for d in [4]
301+
d1 = d
302+
303+
a1.should == a
304+
b1.should == b
305+
c1.should == c
306+
d1.should == d
307+
inside_proc.should == 42
308+
end
309+
end
310+
local_variables.sort.should == [:a, :a1, :b, :b1, :c, :c1, :d, :d1, :inside_proc]
311+
}.call
312+
end
313+
end
314+
local_variables.sort.should == [:a, :a1, :b, :b1]
315+
end
316+
317+
it "can be nested with forward arguments" do
318+
def bar(*args)
319+
args
320+
end
321+
322+
def foo(...)
323+
for a in [1]
324+
r = bar(...)
325+
end
326+
r
327+
end
328+
329+
foo(2, 3).should == [2, 3]
330+
end
331+
234332
it "does not try to access variables outside the method" do
235333
ForSpecs::ForInClassMethod.foo.should == [:bar, :baz]
236334
ForSpecs::ForInClassMethod::READER.call.should == :same_variable_set_outside

0 commit comments

Comments
 (0)