Find binding locals by walking the dynamic scopes · jruby/jruby@d2e56a0 · GitHub
Skip to content

Commit d2e56a0

Browse files
committed
Find binding locals by walking the dynamic scopes
Binding#local_variable_get and #local_variable_set took a variable's depth from the static scopes and used it to index the dynamic ones. The two chains don't line up inside a for loop: the loop body gets its own dynamic scope in the interpreter, but a block inside it has the enclosing method's static scope as its parent. So from a block in a for loop, the depth landed one scope short, on the loop body's empty scope, and raised "DynamicScope0 only supports scopes with 0 variables". Walk the dynamic scopes instead and use the first one whose static scope has the variable, stopping at the method's scope as before. Fixes #9849
1 parent 41a7c98 commit d2e56a0

3 files changed

Lines changed: 48 additions & 10 deletions

File tree

‎core/src/main/java/org/jruby/RubyBinding.java‎

Lines changed: 30 additions & 10 deletions

‎spec/ruby/core/binding/local_variable_get_spec.rb‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@
3636
}.call.should == 10
3737
end
3838

39+
it "gets a local variable from a block inside a for loop" do
40+
results = []
41+
for i in 1..2
42+
-> { results << binding.local_variable_get(:i) }.call
43+
end
44+
45+
results.should == [1, 2]
46+
end
47+
3948
it 'gets a local variable defined using eval()' do
4049
bind = binding
4150
bind.eval('number = 10')

‎spec/ruby/core/binding/local_variable_set_spec.rb‎

Lines changed: 9 additions & 0 deletions

0 commit comments

Comments
 (0)