-
Notifications
You must be signed in to change notification settings - Fork 47
Using null conditional assignment
Vadim Dyachenko edited this page Jan 29, 2021
·
1 revision
Sometimes known as null coalescing assignment or logical nullish assignment, ??=
is a shorthand "operator" for assigning something into a variable if it is currently set to undefined
.
So,
a.b ??= c;
very literally translates to
if (a.b == undefined) a.b = c;
in the saved GML file. Should you use ++
or --
in the left-hand expression, you are your own enemy.
This is primarily useful for optional arguments in GMS2.3, like so:
function test(a, b, c) {
b ??= "b";
c ??= "c";
show_debug_message([a, b, c]);
}
// ...
test(1); // [1, b, c]
test(1, 2); // [1, 2, c]
test(1, 2, 3); // [1, 2, 3]
- Left-hand expressions may not contain function calls.
Or, rather, you can use them and GMEdit will save the code correctly, but will not collapse it back on load since I'm parsing the if-statement with a regular expression.
GML does not have inline assignments and inline blocks to allow for variously unusual manipulations that Babel does, therefore you cannot have these without at least one script call overhead. If that does not bother you, feel free to use #mfunc:
2.2 (in script ncset
):
/// ncset(val)
/// @param val
globalvar ncval;
ncval = argument0;
return argument0 != undefined;
2.3:
globalvar ncval;
function ncset(val) {
ncval = val;
return val != undefined;
}
Macro function block (placed in the same script):
// equivalent of `a ?? b`
#mfunc ncand(one, two) (ncset(one) ? ncval : two)
// equivalent of `arr?[ind]`
#mfunc ncarr(arr, ind) (ncset(arr) ? ncval[ind] : undefined)
// equivalent of `obj?.field`
#mfunc ncdot(obj, field) (ncset(obj) ? ncval.field : undefined)
And then:
var z = undefined, a = 1;
trace(ncand(z, a)); // 1
trace(ncand(a, z)); // 1
trace(ncand(a, 2)); // 1
var arr = [1, 2, 3];
trace(ncarr(z, 1)); // undefined
trace(ncarr(arr, 1)); // 2
var st = { one: "one!" }
trace(ncdot(z, one)); // undefined
trace(ncdot(st, one)); // "one!"
-
ncarr
will reasonably crash when accessing indexes out of range.
Adding these checks will cost you some performance. -
ncdot
will reasonably crash when accessing missing variables.
Adding a check for that will cost you some performance.
- Smart auto-completion
- Types
- JSDoc tags (incl. additional ones)
- @hint tag (mostly 2.3)
- `vals: $v1 $v2` (template strings)
- #args (pre-2.3 named arguments)
- ??= (for pre-GM2022 optional arguments)
- ?? ?. ?[ (pre-GM2022 null-conditional operators)
- #lambda (pre-2.3 function literals)
- => (2.3+ function shorthands)
- #import (namespaces and aliases)
- v:Type (local variable types)
- #mfunc (macros with arguments)
- #gmcr (coroutines)