SET EXPR
Runs a short block of Perl and stores whatever it produces in one stash key. Use it when the value cannot be written as a template: a lookup in the database, a calculation, a list built from other lists, a string cut apart and put back together.
For a plain value or a ${var} template, SET VAR is shorter and safer.
When the block runs long, writes several keys, or would read better in JavaScript,
Server CODE takes the same code in either language. Neither op traps
errors: a run-time failure stops the rule in both.
Fields¶
Variable¶
The stash key to write. Type the bare name with no ${} wrapper, and keep it flat: a dot is part of
the name rather than a path into nested data.
Leaving it blank does not fail. The op falls back to the node's own name in the rule tree, lowered
and reduced to an identifier, with spaces and punctuation folded to _. A node still called
SET EXPR writes to a key named set_expr. Rename the node to Build app list and the key becomes
build_app_list. That is worth knowing in both directions: renaming a node for readability moves
the key, and every unnamed, unconfigured copy of this op in the same rule fights over the same key.
Expression¶
A code editor with Perl highlighting. The block can be several statements long. The value assigned is the value of the last statement, in the same way a function returns its last expression, so end the block with the thing you want rather than with a semicolon-terminated side effect.
Placeholders are not expanded here. ${foo} inside the expression stays a literal dollar-brace
string. Read the stash directly instead: the stash is in scope as a hash reference named stash, so
$$stash{foo} gives you the key foo, and you can assign to other keys the same way.
The code is spliced into the rule and compiled with it, which has two consequences worth planning around:
- A syntax error is caught when you save the rule, not when the job runs. The designer refuses the
save with a
DSL validation failedmessage naming the line, and offersIgnore and Savebeside it. Take that offer and the rule is stored broken: the next run stops before its first op, because the whole rule is compiled in one piece. - A run-time error, a division by zero or a lookup against a collection that is not there, throws
and stops the rule at that point. There is no trap around the block and no default value. Wrap
the op in TRY statement with a
CATCH statement, or set the node's
Error Handlingto trap or ignore errors, when the rule should carry on.
An empty expression stores nothing usable and leaves the key undefined.
Whatever the block returns keeps its type. Return a list reference and the key holds a list. Return
a resource and the key holds a resource, ready for ${myvar.name} later. Return nothing at all and
the key is undefined, which reads as empty to every condition op.
What later ops see¶
The key is written into the same stash every other op reads, so the next op can pick it up with
${myvar} straight away. Nothing about the value is recorded anywhere else. The job log gets one
entry for the op, carrying the node's name and nothing more, so neither the expression nor the value
it produced shows up there. To see what was computed, follow the op with
LOG Message.
Assignments the expression makes to other stash keys stick too. That is a legitimate way to set several keys at once, but it hides the writes from anyone reading the rule tree, so prefer one op per key unless the values are computed together.
During a rollback the op runs again unless you clear Run Rollback on the
node. Expressions with side effects outside the stash, a write to a collection or a file, will
therefore happen twice over the life of a failed job. Either make them idempotent or restrict the
direction on the node.
Combining with other ops¶
Compute a value here, branch on it with IF var condition THEN, which reads the stash without any code at all.
Return a list and hand it straight to FOREACH CI or FOREACH file/item. Building the list with repeated PUSH VAR ops is usually clearer when the entries arrive one at a time.
For JavaScript rather than Perl, SET JS EXPR assigns the result of a JavaScript expression to a stash key, and falls back to the node's name the same way when you leave its variable blank.
Examples¶
Derive a short branch name from a topic title.
Variable branch_name
Expression my $t = $$stash{topic_title} // 'none';
$t =~ s/\W+/-/g;
lc substr( $t, 0, 40 );
Build a comma-separated list for a command line, dropping blanks.
Variable app_list
Expression join ',', grep { length } @{ $$stash{apps} || [] };
Keep the result as a real list so a loop op can walk it.
Variable ports
Expression [ 8080, 8081, 8082 ];