I'm setting a variable on an object like this:
$new_var = @( $my_obj->var_value ) ?: '';
But this can be done with the null coalescing operator as well:
$new_var = $my_obj->var_value ?? '';
I'm thinking that the first option is the safest choice, since if $my_obj
is null, then $my_obj->var_value
would throw a runtime error, trying to access var_value
on a null object. Or what?
But then my question is, when is it the better choice to ever use ??
over the single-line ternary shorthand @( $foo->bar ) ?: ''
?
CodePudding user response:
The @
operator is sometimes called the "shut up" operator: it silences any and all warnings and errors produced by the given statement. That makes it a rather crude tool: rather than saying "I am aware of a specific case in this code which I need to handle", it says "whatever goes wrong, just carry on and don't tell me about it".
In contrast, the ??
operator (and the newer ?->
operator) handle one specific case: the left-hand side might be null or unset, and you want to define the behaviour if it is.
The effect of the two expressions is probably quite similar in this case, but the intent with the ??
operator is much clearer.
Even better is to write code where you don't need such cases at all - for instance, a private property that is only written in the constructor is always in a known state; a public method returning that value can then return it without extra error suppression.
So instead of:
class MyClass {
public $var_value;
}
$my_obj = new MyClass;
// I might have forgotten to set the property, so coalesce it
echo $my_obj->var_value ?? '';
You can write:
class MyClass {
private string $var_value;
public function __construct(string $var_value) {
$this->var_value = $var_value;
}
public function get_var_value() {
return $this->var_value;
}
}
$my_obj = new MyClass('hello');
// No way for this to error, so no extra handling needed
echo $my_obj->get_var_value();