Optional Chaining in Latte: $var?->call()?->elem[1]?->item

David Grudl
Nette Core | 8227
+
+15
-

I tried to add optional chaining to Latte (2.6-dev):

{if $blogPost?->count('*')}  // means if (isset($blogPost) && $blogPost->count('*'))
	...
{/if}

{$order->item?->name}  // means isset($order->item) ? $order->item->name : null

So please try it, if it does not interfere with something, so I can release it soon.

Felix
Nette Core | 1199
+
0
-

Excellent!

David Grudl
Nette Core | 8227
+
0
-

Unfortunately, there is one complication. Latte knows the so-called „short ternary operator“ {$a ? $b}, where the third part is missing. It means $a ? $b : null.

So it is then unclear whether this expression $a->items?['1'] means short ternary $a->items ? ['1'] : null or optional chaining isset($a->items['1']) ? $a->items['1'] : null.

From my point of view, it would be better to prefer optional chaining, but it is BC break.

David Grudl
Nette Core | 8227
+
0
-

It's not entirely accurate that this $order->item?->name is translated as isset($order->item) ? $order->item->name : null. In fact, a null coalescing operator is used to remove twice evaluations and intermediate values are cached.

So $order->item?->name Latte translates to (($_tmp = $order->item ?? null) === null ? null : $_tmp->name).

CZechBoY
Member | 3608
+
0
-

So lets allow it only for object access without bc break and not implement chain array access. What do you think?

David Grudl
Nette Core | 8227
+
+1
-

Yeah, I'll do it just for non-colliding syntax and the rest later.