Subroutines and scripts

XSharper has a concept of a subroutine, that accepts 0 or more arguments and returns a single object value.

<!-- SUB1.XSH. Calculate squares of 20 and 50 -->
<xsharper>
	<set a="${=20}" />
	<call subId="square" outTo="result">
		<param>${a}</param>
	</call>
	<print>${a}*${a} = ${result}</print>
	<print>50*50 = ${=square(50)}</print>
	
	<!-- Subroutines -->
	<sub id="square">
		<param name="n" required="true" />
		<set ret="${=$n*$n}" />
		<return>${ret}</return>
	</sub>
</xsharper>

As seen above, subroutines may be invoked directly from the expressions.

To execute square subroutine from another script, it's possible to use include action:

<!-- SUB2.XSH. Calculate square of a value specified as a command-line argument -->
<xsharper>
	<include from="sub1.xsh" />
	<param name="v" required="true">Value to calculate square</param>

	<print>${v}*${v} = ${=square($v)}</print>
</xsharper>

Finally, execute another script as if it was executed from command line:

<!-- SUB3.XSH. Print square of a value using SUB2.XSH -->
<xsharper>
	<exec from="sub2.xsh">
		<param>500</param>
	</exec>
</xsharper>

Isolation level

By default, subroutines have read-only access to the variables of the caller and any set or changed variables in the subroutine body are restored.

<set x="50" />
<print>Before call x=${x}</print>
<call subId="sub" isolation="default" />
<print>After call x=${x}</print>

<sub id="sub">
	<print>Sub. Initially x=${x|'Undefined'}.</print>
	<set x="100" />		
	<print>Sub. Later x=${x}.</print>
</sub>

The code above will print:
Before call x=50
Sub. Initially x=50.
Sub. Later x=100.
After call x=50

This behaviour can be changed by caller, by changing attribute isolation

With isolation="none", when no variables are restored, the output will be

Before call x=50
Sub. Initially x=50.
Sub. Later x=100.
After call x=100

With isolation="high", the subroutine will have a totally clean variable list, w/o access to the caller variables at all:

Before call x=50
Sub. Initially x=Undefined.
Sub. Later x=100.
After call x=50