On 09/09/2017 12:21, ilija.tov...@me.com wrote:
Hi everybody!
Has this idea been discussed before?
I find myself writing switch statements in PHP quite rarely. This has a few
reasons:
1. It doesn’t have a "strict_types” version
2. It is quite verbose (lots of breaks)
3. It is a statement rather than an expression
Often, if / elseif statements turn out to be shorter, safer and easier to read
than the switch statement.
I've had the idea kicking around my head for some time of a "switch-use"
statement. I keep hoping to find the time to play around with the PHP
parser and see if I can write a proof of concept implementation, just as
an excuse to get deeper into the source, but since this has come up,
I'll outline the idea.
The general form would be "switch ( expression ) use ( op ) { ... }",
where "op" is any binary operator which gives a boolean result, and the
rest looks the same as a normal PHP switch statement.
The simplest example would be to do a strict comparison by using "===":
switch ( someFunction() ) use ( === ) {
case 42:
// ...
break;
case '42':
// ...
break;
}
Which would approximately de-sugar to:
$temp = someFunction();
switch ( true ) {
case $temp === 42:
// ...
break;
case $temp === '42':
// ...
break;
}
As you can see, the switch(true) version has to use an explicit variable
to avoid re-computing the expression, which switch does for you, and you
then have to repeat the "$temp ===", obscuring the fact that all cases
are checking the same thing. A normal switch, however, can't distinguish
42 from '42', because it uses the == comparison rules.
If this were the only useful operator, we might just call it "switch
strict" or something, but here are a couple of examples with other
operators:
// Generic exception handling function
// Also useful when accepting various incompatible implementations of
something and wrapping or converting them
switch ( $e ) use ( instanceof ) {
case FooException:
case BarException:
// ...
break;
case SomeOtherException:
// ...
break;
}
// Dividing a circle into arbitrary sectors, based on this Stack
Overflow question: https://stackoverflow.com/q/44183771/157957
// Note the ability to place "default" at the top, rather than
duplicating code in an else clause
switch ( $angle ) use ( <= ) {
case 30:
default:
return Direction::Right;
break;
case 60:
return Direction::UP_RIGHT;
break;
case 120:
return Direction::UP;
break;
case 150:
return Direction::UP_LEFT;
break;
case 210:
return Direction::LEFT;
break;
case 240:
return Direction::DOWN_LEFT;
break;
case 300:
return Direction::DOWN;
break;
case 330:
return Direction::DOWN_RIGHT;
break;
}
There are a couple of ways to expand this further, if we wanted:
* Allow operators whose result isn't strictly a boolean, such as bitwise &
* Allow any 2-parameter callable in place of an operator, to have more
complex comparisons. With Andrea's "operator functions" suggestion,
operators would technically just be a subset of this anyway.
The below would be quite useful, but unfortunately preg_match takes
($pattern, $subject) and this would need ($subject, $pattern), so you'd
need some extra transform:
switch ( $message ) use ( 'preg_match' ) {
case '/^Missing parameter:/':
case '/^Unexpected parameter:/':
return self::MALFORMED_REQUEST;
break;
case '/.*try again later.$/':
return self::TEMPORARY_ERROR;
break;
}
Any thoughts?
Regards,
--
Rowan Collins
[IMSoP]
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php