-
Notifications
You must be signed in to change notification settings - Fork 0
Make compatible with PHP's pattern matching RFC #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
In Python, the following works: match command.split():
case ["drop", *objects]:
for obj in objects:
character.drop(obj, current_room)
# The rest of your commands go hereMaybe we should be able to bind to variables when using the spread operator, too? The rest pattern gathers all unmatched values into an array and passes it to the binding variable: if ([1, 2, 3] is [1, ...$rest]) {
var_dump($rest); // [2, 3]
}
if (['one' => 1, 'two' => 2] is (['one' => 1, ...$rest]) {
var_dump($rest); // ['two' => 2]
}🧪 https://gist.github.com/thekid/5f85c8ec6e14644b06cb9b100644529e See also: |
The latter is only for numerical comparison
|
Variable bindings can replace destructuring assignments in most cases:
The if ($list is [$a, $b, ...]) {
var_dump($a, $b);
}
// Equivalent of, guarded by type and length checks to prevent errors
if (is_array($list) && sizeof($list) >= 2) {
[$a, $b]= $list;
var_dump($a, $b);
} |
|
Following the idea of replacing destructuring assignments, I wanted to see whether I would be able to parse Composer files. Here's what I came up with: use lang\FormatException;
use util\cmd\Console;
class ComposerFile {
private function __construct(
public private(set) string $name,
public private(set) ?string $type,
public private(set) array $dependencies,
public private(set) array $development= [],
public private(set) array $scripts= [],
) { }
private static function parse(string $input): self {
if (json_decode($input, true) is [
'name' => $name & string,
'type' => $type & ?string ?? null,
'require' => $dependencies & array,
'require-dev' => $development & array ?? [],
'scripts' => $scripts & array ?? [],
...
]) return new self($name, $type, $dependencies, $development, $scripts);
throw new FormatException('Cannnot parse given input');
}
public static function main(array $args): void {
file_get_contents($args[0])
|> self::parse(...)
|> Console::writeLine(...)
;
}
}The missing piece is having a way to make certain keys optional, which I implemented using the null-coalescing operator, inspired by https://wiki.php.net/rfc/destructuring_coalesce. Note: This RFC was declined for confusing syntax, see https://externals.io/message/118829, we might need a different approach here too. JS uses 🧪 https://gist.github.com/thekid/97646f250ac2868fb98052019fe8973d (with |
|
Another interesting idea is integrating try {
// ...
} catch ($e is Error(status: 404)) {
echo 'Not found!';
}🧪 https://gist.github.com/thekid/6f6798bc05995caac6b7e825d6d5a76f |
This is consistent with the regular `match` expression
|
Supporting implementations of the if (new ArrayObject([1, 2, 3]) is [$a, $b, $c]) {
var_dump($a, $b, $c); // 1 2 3
}🧪 https://gist.github.com/thekid/773803d84b357799ffd65f855bc0181c |
This PR extends the basic type matching capabilities and implements all of https://wiki.php.net/rfc/pattern-matching
Implementation status
&and|match (...) is, see https://wiki.php.net/rfc/pattern-matching#match_is_placementNotes
See also