Re: [Discussion] Implicitly backed enums
| From: | Larry Garfield | Date: | Thu, 23 May 2024 13:03:21 +0000 |
| Subject: | Re: [Discussion] Implicitly backed enums | ||
| References: | 1 2 3 4 5 6 7 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-123413@lists.php.net to get a copy of this message | ||
On Thu, May 23, 2024, at 1:35 AM, Robert Landers wrote:
> For what it's worth, the biggest downside to this decision is in
> upgrading old/legacy projects to use enums. Most of the time, you want
> to convert a const to an enum, and that also usually means it will be
> a backed enum. Since there's no way to cast a backed enum to a
> string/int, you have to instead add ->value (I really don't understand
> the difference; casting would have been much more elegant); this
> almost always results in lots of hidden runtime errors. At the last
> couple of places, after seeing the damage the conversion could do,
> doing this conversion was simply off-limits. Maybe by now, there is
> some reliable tooling to handle this automatically... I haven't
> looked. The point remains that it is a strange decision to use
>
->value but not allow
> (string) or (int) or allow even
> implementing it yourself.
Union types are the correct solution here:
function move(string $direction, Player $player) { ... }
becomes
function move (Direction|string $direction, Player $player) {
if (is_string($direction)) {
$direction = Direction::from($direction);
}
// We now have a normalized enum to work with.
}
The only catch there is inheritance, where it works fine if you jut expand the implementers/children
first, then the interface/parent. Then you can remove the string option at some point in the
future, going the other way (interface/parent, then implementer/child).
--Larry Garfield