lib/ruote/exp/fe_iterator.rb in ruote-2.2.0 vs lib/ruote/exp/fe_iterator.rb in ruote-2.3.0

- old
+ new

@@ -1,7 +1,7 @@ #-- -# Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com +# Copyright (c) 2005-2012, John Mettraux, jmettraux@gmail.com # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell @@ -46,11 +46,12 @@ # # The 'on' attribute is used to instruct the expression on which list/array # it should iterate. # # The 'to' attribute takes two forms, :to_v, :to_var, :to_variable or - # :to_f, :to_fld, :to_field. + # :to_f, :to_fld, :to_field. Finally, you can write :to => 'field_name', + # :to => 'f:field_name' or :to => 'v:variable_name'. # # The 'to' attribute instructs the iterator into which variable or field # it should place the current value (the value being iterated over). # # If there is no 'to' specified, the current value is placed in the variable @@ -60,11 +61,11 @@ # (think Ruby's #each_with_index). # # The 'on' attribute can be replaced by a :time or a :branches attribute. # # pdef = Ruote.process_definition :name => 'test' do - # iterator :times => '3' + # iterator :times => '3' do # participant 'accounting' # end # end # # will be equivalent to @@ -75,22 +76,47 @@ # participant 'accounting' # participant 'accounting' # end # end # + # === variables and scope # + # Starting with ruote 2.3.0, the iterator doesn't create a new scope for + # its variables, it uses the current scope. + # + # The old behaviour can be obtained by setting :scope => true, as in: + # + # iterator :on => [ 1, 2, 3 ], :to_v => 'x', :scope => true do + # # ... + # end + # + # A corollary: by default, the variables set by the iterator or within it + # stick in the current scope... + # + # # == the classical case # - # Iterating over a workitem field : + # Iterating over a workitem field: # # pdef = Ruote.process_definition :name => 'test' do # iterator :on_field => 'customers', :to_f => 'customer' # participant '${f:customer}' # end # end # + # It's equivalent to: # + # pdef = Ruote.process_definition :name => 'test' do + # iterator :on => '$f:customers', :to_f => 'customer' + # participant '${f:customer}' + # end + # end + # + # "$f:customers" yields the actual array, whereas "${f:customers}" + # yields the string representation of the array. + # + # # == break/rewind/continue/skip/jump # # The 'iterator' expression understands a certain the following commands : # # * break (_break) : exits the iteration @@ -188,46 +214,55 @@ h.list = determine_list h.to_v, h.to_f = determine_tos h.position = -1 - h.to_v = 'i' if h.to_v == nil && h.to_f == nil + h.to_v = 'i' unless h.to_v or h.to_f move_on end protected def move_on(workitem=h.applied_workitem) - h.position += 1 + current_position = h.position + h.position = 0 if h.position == -1 + child_id = workitem['fei'] == h.fei ? + 0 : Ruote::FlowExpressionId.new(workitem['fei']).child_id + 1 + com, arg = get_command(workitem) - return reply_to_parent(workitem) if com == 'break' - case com + + when 'break' then return reply_to_parent(workitem) + when 'rewind', 'continue' then h.position = 0 - when 'skip' then h.position += arg + when 'skip' then h.position += (arg + 1) when 'jump' then h.position = arg + + else + h.position = h.position + 1 if child_id >= tree_children.size end h.position = h.list.length + h.position if h.position < 0 + return apply_child(child_id, workitem) if h.position == current_position + val = h.list[h.position] return reply_to_parent(workitem) if val == nil - (h.variables ||= {})['ii'] = h.position + set_variable('ii', h.position) if h.to_v - h.variables[h.to_v] = val + set_variable(h.to_v, val) else #if h.to_f workitem['fields'][h.to_f] = val end apply_child(0, workitem) - # persist is done in there end end end