Quantcast
Channel: A Day In The Life Of...
Viewing all articles
Browse latest Browse all 59

Saffire update may 2013: coalesce

$
0
0

One of the things that happens over and over again is that you need to check a value, and if it’s not set, it should set a default value. Normally, these variables could be initially set by properties, but sometimes you don’t have any control on initialization. For instance, when these values come from users.

In PHP:

if (isset($_POST['variable'])) {
  $a = $_POST['variable'];
} else {
  $a = "default value";
}

or through the ternary operator:

$a = $_POST['variable'] ? $_POST['variable'] : "default";

One of the problems with these constructions, is that when the first operand is true (and thus the default value is not used), the first operand is evaluated twice. As an example:

$a = 0;
function foo() {
  global $a;
  $a++;
  return $a;
}

print foo() ? foo() : "bar"; // 2

This will output “2″. Once foo() is called for the evaluation, the second time foo() is called for actually returning that variable. Since PHP 5.3, the ternary operator can leave out the middle part, in which case it will actually return the first part if this is evaluates to true. This is NOT equivalent to the example above, as this “shortsyntax” actually evaluates once:

$a = 0;
function foo() {
  global $a;
  $a++;
  return $a;
}

print foo() ?: "bar"; // 1

In the last few days, Kevin (@_ikke_) has implemented this feature through the coalesce operator which can be used like this in Saffire:

import io;

val = "";
io.print( val ?? "default", "\n");

Again, just like PHP shortcut ternary operator, the coalesce operator will use the first value if this value evaluates to boolean “true”. Internally, it will try and implicitly cast this through the __boolean() method on the object given. If this evaluates to false, it will return the value right after the ??.
Both the left side and the right side of the ?? can be expressions.

It’s even possible to “chain” so we can coalesce multiple values, ie: we can find the first non-false value easily:

io.print( (user.firstname() ?? user.lastname() ?? user.email() ?? "unknown user"), "\n");

Note that currently you need to add () if you chain multiple coalesce operators. In this example, we print either the users firstname, lastname, email address or just “unknown user”, which ever is defined first.

Because coalesce internally is structured differently than simple if-else or a ternary operation, it’s much more optimal to use coalesce.

Share


Viewing all articles
Browse latest Browse all 59

Trending Articles