[[expressions-ref-variables]]
= Variables

You can reference variables in an expression by using the `#variableName` syntax. Variables
are set by using the `setVariable()` method in `EvaluationContext` implementations.

[NOTE]
====
Valid variable names must be composed of one or more of the following supported
characters.

* letters: `A` to `Z` and `a` to `z`
* digits: `0` to `9`
* underscore: `_`
* dollar sign: `$`
====

The following example shows how to use variables.

[tabs]
======
Java::
+
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
----
	Inventor tesla = new Inventor("Nikola Tesla", "Serbian");

	EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();
	context.setVariable("newName", "Mike Tesla");

	parser.parseExpression("name = #newName").getValue(context, tesla);
	System.out.println(tesla.getName());  // "Mike Tesla"
----

Kotlin::
+
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
----
	val tesla = Inventor("Nikola Tesla", "Serbian")

	val context = SimpleEvaluationContext.forReadWriteDataBinding().build()
	context.setVariable("newName", "Mike Tesla")

	parser.parseExpression("name = #newName").getValue(context, tesla)
	println(tesla.name)  // "Mike Tesla"
----
======


[[expressions-this-root]]
== The `#this` and `#root` Variables

The `#this` variable is always defined and refers to the current evaluation object
(against which unqualified references are resolved). The `#root` variable is always
defined and refers to the root context object. Although `#this` may vary as components of
an expression are evaluated, `#root` always refers to the root.

The following example shows how to use the `#this` variable in conjunction with
xref:core/expressions/language-ref/collection-selection.adoc[collection selection].

[tabs]
======
Java::
+
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
----
	// Create a list of prime integers.
	List<Integer> primes = List.of(2, 3, 5, 7, 11, 13, 17);

	// Create parser and set variable 'primes' as the list of integers.
	ExpressionParser parser = new SpelExpressionParser();
	EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();
	context.setVariable("primes", primes);

	// Select all prime numbers > 10 from the list (using selection ?{...}).
	String expression = "#primes.?[#this > 10]";

	// Evaluates to a list containing [11, 13, 17].
	List<Integer> primesGreaterThanTen =
			parser.parseExpression(expression).getValue(context, List.class);
----

Kotlin::
+
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
----
	// Create a list of prime integers.
	val primes = listOf(2, 3, 5, 7, 11, 13, 17)

	// Create parser and set variable 'primes' as the list of integers.
	val parser = SpelExpressionParser()
	val context = SimpleEvaluationContext.forReadWriteDataBinding().build()
	context.setVariable("primes", primes)

	// Select all prime numbers > 10 from the list (using selection ?{...}).
	val expression = "#primes.?[#this > 10]"

	// Evaluates to a list containing [11, 13, 17].
	val primesGreaterThanTen = parser.parseExpression(expression)
			.getValue(context) as List<Int>
----
======

The following example shows how to use the `#this` and `#root` variables together in
conjunction with
xref:core/expressions/language-ref/collection-projection.adoc[collection projection].

[tabs]
======
Java::
+
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
----
	// Create parser and evaluation context.
	ExpressionParser parser = new SpelExpressionParser();
	EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();

	// Create an inventor to use as the root context object.
	Inventor tesla = new Inventor("Nikola Tesla");
	tesla.setInventions("Telephone repeater", "Tesla coil transformer");

	// Iterate over all inventions of the Inventor referenced as the #root
	// object, and generate a list of strings whose contents take the form
	// "<inventor's name> invented the <invention>." (using projection !{...}).
	String expression = "#root.inventions.![#root.name + ' invented the ' + #this + '.']";

	// Evaluates to a list containing:
	// "Nikola Tesla invented the Telephone repeater."
	// "Nikola Tesla invented the Tesla coil transformer."
	List<String> results = parser.parseExpression(expression)
			.getValue(context, tesla, List.class);
----

Kotlin::
+
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
----
	// Create parser and evaluation context.
	val parser = SpelExpressionParser()
	val context = SimpleEvaluationContext.forReadWriteDataBinding().build()

	// Create an inventor to use as the root context object.
	val tesla = Inventor("Nikola Tesla")
	tesla.setInventions("Telephone repeater", "Tesla coil transformer")

	// Iterate over all inventions of the Inventor referenced as the #root
	// object, and generate a list of strings whose contents take the form
	// "<inventor's name> invented the <invention>." (using projection !{...}).
	val expression = "#root.inventions.![#root.name + ' invented the ' + #this + '.']"

	// Evaluates to a list containing:
	// "Nikola Tesla invented the Telephone repeater."
	// "Nikola Tesla invented the Tesla coil transformer."
	val results = parser.parseExpression(expression)
			.getValue(context, tesla, List::class.java)
----
======

