Class: Opal::Rewriters::ForRewriter
- Defined in:
- lib/opal/rewriters/for_rewriter.rb
Defined Under Namespace
Classes: LocalVariableAssigns
Constant Summary
Constants inherited from Base
Instance Attribute Summary
Attributes inherited from Base
Class Method Summary collapse
Instance Method Summary collapse
-
#on_for(node) ⇒ Object
Handles for i in 0..3; j = i + 1; end.
Methods inherited from Base
#append_to_body, #begin_with_stmts, #dynamic!, #error, #on_top, #prepend_to_body, #process, s, #s, #stmts_of
Class Method Details
.next_tmp ⇒ Object
12 13 14 15 16 |
# File 'lib/opal/rewriters/for_rewriter.rb', line 12 def self.next_tmp @counter ||= 0 @counter += 1 :"$for_tmp#{@counter}" end |
.reset_tmp_counter! ⇒ Object
8 9 10 |
# File 'lib/opal/rewriters/for_rewriter.rb', line 8 def self.reset_tmp_counter! @counter = 0 end |
Instance Method Details
#on_for(node) ⇒ Object
Handles for i in 0..3; j = i + 1; end
The problem here is that in Ruby for loop makes its
loop variable + all local variables available outside.
I.e. after this loop variable i
is 3 and j
is 4
This class rewrites it to the following code: j = nil i = nil (0..3).each { |__jstmp| i = __jstmp; j = i + 1 }
Complex stuff with multiple loop variables: for i, j in [[1, 2], [3, 4]]; end Becomes multiple left-hand assignment: i = nil j = nil [[1, 2], [3, 4]].each { |__jstmp| i, j = __jstmp }
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/opal/rewriters/for_rewriter.rb', line 38 def on_for(node) loop_variable, loop_range, loop_body = *node # Declare local variables used in the loop and the loop body at the outer scope outer_assignments = generate_outer_assignments(loop_variable, loop_body) # Generate temporary loop variable tmp_loop_variable = self.class.next_tmp get_tmp_loop_variable = s(:js_tmp, tmp_loop_variable) # Assign the loop variables in the loop body loop_body = prepend_to_body(loop_body, assign_loop_variable(loop_variable, get_tmp_loop_variable)) # Transform the for-loop into each-loop with updated loop body node = transform_for_to_each_loop(node, loop_range, tmp_loop_variable, loop_body) node.updated(:begin, [*outer_assignments, node]) end |