10 Replies - 794 Views - Last Post: 29 August 2019 - 10:03 AM Rate Topic: -----

#1 CilVine   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 29
  • Joined: 04-January 16

Cannot 'throw' in shorthand conditionals

Posted 27 August 2019 - 04:41 PM

We know that this works:-

 

    return !empty($a) ? "okay" : "nope"; 




And, also this (equivalent):-

 

if(!empty($a)) {
    return "okay"; 
} else { 
    return "nope"; 
}  




However, even though this works:-

 

if($c) {
    return "you're in the clear";
} else {
    return throw new Exception("blah, blah, blah");
} 




This does NOT work;-

    return $c ? "you're in the clear" : throw new Exception("blah, blah, blah"); 




1. Why is this functionality (Eg; allowing to 'throw' an Exception) omitted from shorthand conditionals?.

2. What could be a suitable workaround (whilst STILL using shorthand)? If possible?

Is This A Good Question/Topic? 0
  • +

Replies To: Cannot 'throw' in shorthand conditionals

#2 ArtificialSoldier   User is online

  • D.I.C Lover
  • member icon

Reputation: 2365
  • View blog
  • Posts: 7,219
  • Joined: 15-January 14

Re: Cannot 'throw' in shorthand conditionals

Posted 27 August 2019 - 04:58 PM

I suspect the reason for that is because the ternary operator is an expression that evaluates to a value, and I bet that throw does not evaluate to anything, it cannot be considered a value. These probably also don't work for the same reason:

$var = throw new Exception...

echo throw new Exception...


That makes sense to me, I don't know what the "value" of a throw statement would be. That would be like trying to do this:

$var = while (true) {

}


The while statement, like the throw statement, does not belong on the right-hand side of an assignment operator, or anywhere else that requires a value, like the ternary operator you're trying to use.

It also does not make sense to use throw as a value for return. What do you expect throw to return?

If you need to throw an exception, then throw an exception, and then return a value. Throwing an exception is not a substitute for returning a value. If you have this:

$var = return_or_throw();


What exactly is the value of $var going to be if you try to "return throw"?

I should also point out that your assertion that this works:

if($c) {
    return "you're in the clear";
} else {
    return throw new Exception("blah, blah, blah");
} 


Is not correct:

Quote

Parse error: syntax error, unexpected 'throw' (T_THROW), expecting ';'

Was This Post Helpful? 2
  • +
  • -

#3 Martyr2   User is offline

  • Programming Theoretician
  • member icon

Reputation: 5457
  • View blog
  • Posts: 14,406
  • Joined: 18-April 07

Re: Cannot 'throw' in shorthand conditionals

Posted 27 August 2019 - 05:04 PM

is on the money. The throw exception is a "STATEMENT" and not an expression. The ternary operator works on expressions. Don't confuse this with simply being a shorthand if statement. While they behavior similarly, they are not direct equivalents. Ternary takes a condition and two expressions. :)
Was This Post Helpful? 2
  • +
  • -

#4 CilVine   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 29
  • Joined: 04-January 16

Re: Cannot 'throw' in shorthand conditionals

Posted 27 August 2019 - 07:29 PM

View PostMartyr2, on 27 August 2019 - 05:04 PM, said:

is on the money. The throw exception is a "STATEMENT" and not an expression. The ternary operator works on expressions. Don't confuse this with simply being a shorthand if statement. While they behavior similarly, they are not direct equivalents. Ternary takes a condition and two expressions. :)/>


Thanks for the input.
Was This Post Helpful? 0
  • +
  • -

#5 CilVine   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 29
  • Joined: 04-January 16

Re: Cannot 'throw' in shorthand conditionals

Posted 27 August 2019 - 07:51 PM

View PostArtificialSoldier, on 27 August 2019 - 04:58 PM, said:

I suspect the reason for that is because the ternary operator is an expression that evaluates to a value, and I bet that throw does not evaluate to anything, it cannot be considered a value. These probably also don't work for the same reason:

$var = throw new Exception...

echo throw new Exception...


That makes sense to me, I don't know what the "value" of a throw statement would be. That would be like trying to do this:

$var = while (true) {

}


The while statement, like the throw statement, does not belong on the right-hand side of an assignment operator, or anywhere else that requires a value, like the ternary operator you're trying to use.

It also does not make sense to use throw as a value for return. What do you expect throw to return?

If you need to throw an exception, then throw an exception, and then return a value. Throwing an exception is not a substitute for returning a value. If you have this:

$var = return_or_throw();


What exactly is the value of $var going to be if you try to "return throw"?

I should also point out that your assertion that this works:

if($c) {
    return "you're in the clear";
} else {
    return throw new Exception("blah, blah, blah");
} 


Is not correct:

Quote

Parse error: syntax error, unexpected 'throw' (T_THROW), expecting ';'


Yep. I suppose you're correct.

So, insofar as where exceptions, or errors, are concerned, is there a suggestible workaround, within a shorthand conditional? Particularly in the context of a try/catch block?

    try {

        $b ? /* success */ : /* error */; 

    } catch (Exception $e) { 

        /* error logic here. */

    }



Was This Post Helpful? 0
  • +
  • -

#6 andrewsw   User is offline

  • never lube your breaks
  • member icon

Reputation: 6813
  • View blog
  • Posts: 28,188
  • Joined: 12-December 12

Re: Cannot 'throw' in shorthand conditionals

Posted 28 August 2019 - 04:06 AM

A ternary expression evaluation should not attempt to throw an exception, it would be an unexpected consequence: a side-effect.

If there is some problem with attempting the evaluation then I would even avoid the ternary operator; use a simple if statement and perhaps return some value indicating an issue. If it is appropriate for an exception to be thrown then it is more than likely that there is something fundamentally wrong with the attempt to use the method, rather than directly anything to do with the use of the ternary operator (or equivalent if statement).
Was This Post Helpful? 1
  • +
  • -

#7 ArtificialSoldier   User is online

  • D.I.C Lover
  • member icon

Reputation: 2365
  • View blog
  • Posts: 7,219
  • Joined: 15-January 14

Re: Cannot 'throw' in shorthand conditionals

Posted 28 August 2019 - 09:18 AM

Why is there a requirement that this needs to be part of a ternary conditional expression? Are you in a contest or something? A ternary condition produces a value, that's it's purpose. It is a way to set a value based on a condition. Throw does not have a value, so it does not belong in a ternary expression. If you detect an error condition then throw an exception for it, you still need to return a value though. e.g.:

if ($error) {
  throw new Exception($error_message);
  return false;
}
else {
  return $return;
}


Again, why is it necessary that all of that needs to go inside a ternary expression, why is that a requirement for you? Why not use the best tools for the job instead of trying to use something in some way that it's not supposed to be used?

A ternary expression is not a shorthand if statement. An if statement does not set a value, a ternary expression does. Do not treat them the same way, they have different purposes. If you need an if statement, then use an if statement, that's why it's there. The ternary expression is a special case where you are setting a value based on a condition, it is not a drop-in replacement for every if statement you might come across.
Was This Post Helpful? 0
  • +
  • -

#8 CilVine   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 29
  • Joined: 04-January 16

Re: Cannot 'throw' in shorthand conditionals

Posted 28 August 2019 - 05:30 PM

I did not say it was a requirement.

I am simply asking about the limitation(s) of the ternary statement, as an alternative to the 'if-else' statement. People DO use the ternary statement in place of a regular 'if-else' statement.

Anyway, thank you, for being the person that fully answered my post.

This post has been edited by andrewsw: 29 August 2019 - 01:01 AM
Reason for edit:: removed previous quote, just use the REPLY button

Was This Post Helpful? 0
  • +
  • -

#9 ArtificialSoldier   User is online

  • D.I.C Lover
  • member icon

Reputation: 2365
  • View blog
  • Posts: 7,219
  • Joined: 15-January 14

Re: Cannot 'throw' in shorthand conditionals

Posted 28 August 2019 - 05:55 PM

Quote

I am simply asking about the limitation(s) of the ternary statement, as an alternative to the 'if-else' statement.

That's easy, it's not an alternative to any arbitrary if/else statement. A ternary expression is an assignment statement (it evaluates to a value, that's the purpose). An if statement is a control structure. The two serve different purposes. Control structures do not evaluate to a value, they just control the execution flow.

Quote

People DO use the ternary statement in place of a regular 'if-else' statement.

Do they? You think it's a general-purpose replacement and not a different type of statement? How would I convert this to a ternary expression:

            if ($this->fields['completion_date_type'] == self::COMPLETION_DATE_TYPE_ONE_TIME) {
                $dueDate = $this->fields['completion_date'];
            } else {
                // Completion date type Annual
                try {
                    $cur = new DateTime('@' . $this->fields['completion_date']);
                    $now = mktime(0, 0, 0);
                    while ($cur->getTimestamp() < $now) {
                        $cur->add(new DateInterval('P1Y'));
                    }
                    $dueDate = $cur->getTimestamp();
                } catch (Exception $e) {
                    // completion_date was probably not set.
                    $dueDate = null;
                }
            }


I could start with $dueDate = ($this->fields['completion_date_type'] == self::COMPLETION_DATE_TYPE_ONE_TIME) ? $this->fields['completion_date'] : , but since there's a try/catch block that contains a while loop, and $dueDate can have a value from either the try block or the catch block, what's the syntax for telling it "use this value for $dueDate?" There's not one, I could put all of that code into an anonymous function that returns one of the possible values and do that, but now I've added a function and it's not the same code.

I'm sure you get the point, one of them is specifically an assignment statement, and the other is a control structure. The ternary expression is not a replacement for if/else, it is a replacement for a very specific kind of if/else. If you're not using that specific kind, it's not the right tool.
Was This Post Helpful? 0
  • +
  • -

#10 CilVine   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 29
  • Joined: 04-January 16

Re: Cannot 'throw' in shorthand conditionals

Posted 28 August 2019 - 08:58 PM

"The ternary expression is not a replacement for if/else, it is a replacement for a very specific kind of if/else".
(You have answered yourself, in the case of your second response.)

So, a ternary statement CAN be used instead of an if-else statement. BUT, only in some (but, not all) cases (hence, why it may also be referred to as a 'shorthand' if-else).

You've nailed it. Hence, why I was asking in this case. Clearly, it doesn't apply here. Thanks for the example.

This post has been edited by andrewsw: 29 August 2019 - 01:02 AM
Reason for edit:: removed previous quote, just use the REPLY button

Was This Post Helpful? 0
  • +
  • -

#11 ArtificialSoldier   User is online

  • D.I.C Lover
  • member icon

Reputation: 2365
  • View blog
  • Posts: 7,219
  • Joined: 15-January 14

Re: Cannot 'throw' in shorthand conditionals

Posted 29 August 2019 - 10:03 AM

Quote

So, a ternary statement CAN be used instead of an if-else statement.

That's not true in general. It can only replace this kind of conditional assignment:

if ($condition) {
  $var = $value1;
}
else {
  $var = $value2;
}


Specifically, you need to be assigning one of two possible values to the same variable based on some condition. All other if/else statements do not apply. You can't replace these with it, for example:

if ($condition) {
  $var1 = $value;
}
else {
  $var2 = $value;
}


if ($condition) {
  $var = $value1;
  $var2 = true;
}
else {
  $var = $value2;
  $var2 = false;
}


And, of course, you would not use it to replace any if/else statement that contains any other control structure.

The first case for assignment is common enough that it made sense to make it shorter, but it's just not a replace for any if/else statement you want, so try not to think of it that way. It's not a shorthand if/else, it's an assignment operator.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1