PHPではいわゆるパターンマッチングはできません。
PHP 8.0で導入されたmatch
式は「ちゃんとした」パターンマッチじゃないんだってRFCに書いてあったよ。
うーん… 困った。そうだね、ないなら作ろう。
$result = match (ing($subject, matcher: $_, matched: $m)) {
$_(is: 'ほげ') => 'これはほげだよ',
$_(class: DateTime::class) => "これはDateTimeだよ",
$_([$_->a]) => "要素1 マッチしたよ! {$m->a}",
$_([$_->a, $_->b]) => "要素2 マッチしたよ! {$m->a} {$m->b}",
$_([$_->a, $_->b, $_->c]) => "要素3 マッチしたよ! {$m->a}, {$m->b}, {$m->c}",
$_(['config' => ['password' => $_->pass]]) => "password = {$m->pass}",
$_('/\A〒?(?<up>[0-9]{3})-(?<down>[0-9]{4})\z/u') => "郵便番号は{$m->up}の{$m->down}だよ!",
$_(is_string(...)) => "これは文字列($m->value)だよ",
$_(is_int(...)) => "これは整数($m->value)だよ",
$_(is_float(...)) => "これは浮動小数点数($m->value)だよ",
default => 'not matched',
};
実装したもの
-
is:
マッチャー-
===
で比較するやつ - 普通の
match
の条件節と同じだけど、PHPのmatch
の仕様上普通のマッチングは使えなくなるので仕方なく用意したよ
-
-
class:
マッチャー-
instanceof
でチェックするやつ
-
- 配列マッチャー
- 配列の要素が一致しているかをチェックするやつ
- 配列の中身から値をとりたいときは
$_->hoge
みたいに書くよ- マッチした後から
$m->hoge
でとれるよ
- マッチした後から
- 入れ子になっても動くよ
- 正規表現マッチャー
- 文字列を
preg_match
でマッチさせるよ- マッチした内容は
$m->
でとれるよ
- マッチした内容は
- 文字列を
実装してないもの
- 配列の残りの部分をぐいってまとめてとってくるやつとか
- オブジェクトのプロパティを解体するやつとか
- その他いろいろ
ちゃんとしたパターンマッチって何…? うん、よくわかんない。
コードはどこにあるの
ここにあります。説明は飽きたので各自コードを読んでください。
ライセンスはNYSLとWTFPLのデュアルライセンスです。自由に改造して遊んでね。
このコードがどうして動くのかわからないんだけど
PHPのリファレンス(参照&)の傾向と対策、あるいはさよならを読んでください。
なんでこんな記事を…?
PHPのパターンマッチで遊んでみたに影響を受けました。
出来心でやってみたくなった縛りゲーシリーズ
アロー関数で無名再帰して書いたスターリンソート
そろそろ寝ます。おやすみなさい。