Whatever message this page gives is out now! Go check it out!

Elvis operator

Last update:
Jun 5, 2026
The support has been provided in ColdFusion for the Elvis operator (?:). The Elvis operator is primarily used to assign the ‘right default’ for a variable or an expression.
It returns the resultant value of its left operand's expression, if that resultant value is defined and not null and not a false value. Otherwise, it returns the resultant value of its right operand's expression (the default value).
For instance,
myDisplayName = userName ?: “Anonymous”;
In the above example, if userName is defined and not null and not a false value, it will be assigned to the myDisplayName variable. Otherwise, the value "Anonymous" will be assigned to the myDisplayName variable.
See the following example:
employeeName = getEmployeeName(ID) ?: “Joe”;
In the above example, if getEmployeeName(ID) does not return any value, or if the returned value is a false value, the value "Joe" will be assigned to the employeeName variable.
Similiarly, you can use this operator for Struct:
securityNumber = securityStruct[‘Joe’] ?: “”;

Safer use of implicit arrays and structs in Elvis expressions

ColdFusion allows you to create implicit structs and implicit arrays directly in expressions, for example, { count: 0 } or [1,2,3]. You can use these literals on either side of the Elvis operator, such as:

        // Struct default
        var config = (form ?: { retries: 3, timeout: 1000 });

        // Array default
        var items  = (url.list ?: ["default1", "default2"]);
      
In previous versions of ColdFusion, there were edge cases where using an implicit struct or array literal inside an Elvis expression could unintentionally create a shared variable in the variables scope. When this happened inside cached CFCs or pages accessed by multiple requests in parallel, different requests could end up sharing and mutating the same struct or array, causing race conditions and intermittent errors.
In ColdFusion 2025.0.08, this behavior has been corrected. Implicit structs and arrays used inside Elvis expressions are now treated as request‑local, even in cached components and parallel operations.
Implicit struct and array literals used inside Elvis expressions now behave as you would naturally expect:
  • The literal is created as a local value within the current evaluation.
  • It is not stored as a shared variable in the variables scope.
  • Each request, and each iteration in a parallel operation, gets its own instance, unless you explicitly store it in a shared scope.
For example,

 <cfscript>
    arrayNew(1)
    .resize(1000)
    .set(1, 1000, 1)
    .each(
        () => {
            // This implicit struct remains local to this iteration
            var value = (form.someFlag ?: { count: 0 });

            value.count++;
        },
        true,
        20
    );

    // No unexpected shared "value" struct is created in variables scope
    for (key in variables.keyArray()) {
        writeOutput([key, variables[key]]);
    }
</cfscript>
      
  • Each invocation of the closure gets its own { count: 0 } when the Elvis expression falls back to the right‑hand side.
  • There is no hidden promotion of that struct into variables.
  • Parallel execution does not introduce unintended sharing.
From an application developer’s perspective:
  • When you write an implicit struct or array literal inside an Elvis expression, it behaves like a normal expression‑scope value, not like a hidden shared variable.
  • You no longer need to avoid patterns such as:
    var x = (condition ?: { someKey: "value" });
     
    out of concern for shared‑memory issues in cached CFCs or parallel loops.
  • Existing defensive patterns (for example, moving literals outside expressions to force locality) remain correct, but they are no longer required to avoid the concurrency bug.

Recommended usage patterns

The following patterns are now safe and idiomatic when using the Elvis operator.
Using a struct as the default in an Elvis expression
var options = (url.options
    ?: { retries = 3, timeout = 1000 }
);
options.retries++;
 
Each request receives its own options struct when the default is used.Using an implicit struct with the Elvis operator
var payload = (form.data ?: {});
payload.timestamp = now();
 
If form.data is not defined or is falsy, payload is a new struct {} for that request.Using an implicit array as a default
var items = (url.list
    ?: ["default1", "default2"]
);

arrayEach(
    items,
    function(item) {
        writeOutput(item & "<br>");
    },
    true // even with parallel = true, this array is local
);
 
The default array is not shared between requests or threads.

Share this page

Was this page helpful?
We're glad. Tell us how this page helped.
We're sorry. Can you tell us what didn't work for you?
Thank you for your feedback. Your response will help improve this page.

On this page