Class: Ruote::Exp::SetExpression

Inherits:
SequenceExpression show all
Defined in:
lib/ruote/exp/fe_set.rb

Overview

Setting a workitem field or a process variable.

sequence do
  set :field => 'subject', :value => 'food and beverage'
  set :field => 'date', :val => 'tomorrow'
  participant :ref => 'attendees'
end

:field can be abbreviated to :f or :fld. :variable can be abbreviated to :v or :var. Likewise, :val and :value are interchangeable.

field_value, variable_value

Usually, grabbing a value from a field or a value will look like

set :f => 'my_field', :value => '${v:my_variable}'

But doing those ${} substitutions always result in a string result. What if the variable or the field holds a non-string value ?

set :f => 'my_field', :var_value => 'my_variable'

Is the way to go then. 'set' understands v_value, var_value, variable_value and f_value, fld_value and field_value.

:escape

If the value to insert contains ${} stuff but this has to be preserved, setting the attribute :escape to true will do the trick.

set :f => 'my_field', :value => 'oh and ${whatever}', :escape => true

:override / :over

(attribute introduced in ruote 2.3.0)

When setting a variable with no slash prefix, the target will always be the most local scope. When one wants to purposely override/overwrite an already set variable, the attribute :override can be set to true.

In this example, although the second 'set' happens in its own scope, the variable v0, will be set to 'b' in the initial (top) scope:

pdef = Ruote.define do
  set 'v:v0' => 'a'
  sequence :scope => true do
    set 'v:v0' => 'b', :over => true
  end
end

:over(ride) tells the 'set' expression to locate where the var is set and change the value there.

:over is ignored for process (/) and engine (//) variables. It has no meaning for workitem fields.

When :over is set to 'sub' (or :sub), the :over => true behaviour is followed, but it doesn't cross into the parent subprocess.

ruote 2.0's shorter form

Ruote 2.0 introduces a shorter form for the 'set' expression :

sequence do
  set :field => 'f', :value => 'val0'
  set :variable => 'v', :value => 'val1'
  set :field => 'f_${v:v}', :value => 'val2'
end

can be rewritten as

sequence do
  set 'f:f' => 'val0'
  set 'v:v' => 'val1'
  set 'f:f_${v:v}' => 'val2'
end

since 'f:' is the default for the 'dollar notation', the shortest form becomes

sequence do
  set 'f' => 'val0'
  set 'v:v' => 'val1'
  set 'f_${v:v}' => 'val2'
end

shorter form and non-string values

Dollar substitutions like '$a' will always squash the field or the variable into a string. It's useful, especially when one is doing 'user-$FlowExpression#name', but when the field (or variable) is an array or an hash

set 'f' => '${array}'

will put the string representation of array into the field 'f', not a copy of the array itself.

This will copy the array into the field 'f':

set 'f' => '$f:array'

Note the mandatory 'f:'. There is a thing to be aware of: if the field array is missing, it will resolve into “$f:array” (no substitution at all).

There is always the old-style fallback:

set :field => 'f', :field_value => 'array'

set and rset

Some gems (Sinatra) for example may provide a set method that hides calls to set when building process definitions (see groups.google.com/group/openwferu-users/browse_thread/thread/9ac606e30ada686e)

A workaround is to write 'rset' instead of 'set'.

rset 'customer' => 'Jeff'

unset

'unset' is the counterpart to 'set', it removes a field (or a variable)

unset :field => 'customer_name'
unset :f => 'customer_name'
unset :variable => 'vx'
unset :var => 'vx'
unset :v => 'vx'

or simply

unset 'f:customer_name'
unset 'customer_name' # yes, it's field by default
unset 'v:vx'

using set with a block

(not a very common usage, introduced by ruote 2.3.0)

'set' can be used with a block. It then behaves like a 'sequence' and picks its value in the workitem field named '__result__'.

set 'customer_name' do
  participant 'alice'
  participant 'bob'
end

Here, alice or bob may set the field '__result__' to some value, that will get picked as the value of the field 'customer_name'.

Note that inside the set, a blank variable scope will be used (like in a 'let).

__result__

'set' and 'unset' place the [un]set value in the field named __result__.

sequence do
  set 'f0' => 2
  participant 'x${__result__}''
end

will route a workitem to the participant named 'x2'.

Constant Summary

Constants inherited from FlowExpression

FlowExpression::COMMON_ATT_KEYS

Instance Attribute Summary

Attributes inherited from FlowExpression

#context, #error

Instance Method Summary collapse

Methods inherited from SequenceExpression

#reply

Methods inherited from FlowExpression

#ancestor?, #applied_workitem, #att, #att_text, #attribute, #attribute_text, #attributes, #await, #cancel, #cancel_flanks, #cfei_at, #child_id, #child_ids, #compile_atts, #compile_variables, #debug_id, #deflate, #do, do_action, #do_apply, #do_cancel, #do_fail, #do_pause, #do_persist, #do_reply, #do_reply_to_parent, #do_resume, #do_unpersist, dummy, #fei, fetch, from_h, #handle_on_error, #has_attribute, #initial_persist, #initialize, #is_concurrent?, #iterative_var_lookup, #launch_sub, #lookup_val, #lookup_val_prefix, #lookup_variable, #name, names, #parent, #parent_id, #pause_on_apply, #persist_or_raise, #reply, #root, #root_id, #set_variable, #tree, #tree_children, #try_persist, #try_unpersist, #unpersist_or_raise, #unset_variable, #update_tree, #variables, #wfid

Methods included from WithMeta

#class_def, included

Methods included from WithH

#h, #h=, included, #to_h

Constructor Details

This class inherits a constructor from Ruote::Exp::FlowExpression

Instance Method Details

#applyObject


201
202
203
204
205
206
# File 'lib/ruote/exp/fe_set.rb', line 201

def apply

  h.variables ||= {} # ensures a local scope

  reply(h.applied_workitem)
end

#reply_to_parent(workitem) ⇒ Object


208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/ruote/exp/fe_set.rb', line 208

def reply_to_parent(workitem)

  h.applied_workitem['fields'] = workitem['fields']
    # since set_vf and co work on h.applied_workitem...

  opts = { :escape => attribute(:escape) }
  compiled_atts = compile_atts(opts)

  kv = find_kv(compiled_atts)

  over = attribute(:override) || attribute(:over)
  unset = name == 'unset'

  h.variables = nil
    # the local scope is over,
    # variables set here will be set in the parent scope

  value =
    if tree_children.empty?
      lookup_val(opts)
    else
      h.applied_workitem['fields']['__result__']
    end
      #
      # a nil value is totally OK

  h.applied_workitem['fields']['__result__'] =

    if var_key = has_attribute(:v, :var, :variable)

      set_v(attribute(var_key), value, :unset => unset, :override => over)

    elsif field_key = has_attribute(:f, :fld, :field)

      set_f(attribute(field_key), value, :unset => unset)

    elsif value == nil && kv

      kv << { :unset => unset, :override => over }

      set_vf(*kv)

    elsif kv

      set_vf(kv.first, value, :unset => unset, :override => over)

    else

      raise ArgumentError.new(
        "missing a variable or field target in #{tree.inspect}")
    end

  super(h.applied_workitem)
end