On Wed, May 22, 2024 at 4:13 AM Larry Garfield <la...@garfieldtech.com> wrote: > > On Tue, May 21, 2024, at 6:47 PM, Bilge wrote: > > On 22/05/2024 00:31, Larry Garfield wrote: > >> I could see an argument for auto-populating the backing value off the enum > >> name if it's not specified, something like this: enum Options: string { > >> case First; // This implicitly gets "First" > >> case Second = '2nd'; > >> } > > This seems like a reasonable compromise. In this case, all I need to do > > is change my enum to a backed enum (suffix `: string`) and I get the > > benefits of implicit values. I still like the idea of the same being > > possible for non-backed enums, though I imagine that is a product of my > > naïveté, as I do not tend to think of things in the framing of > > (de)serialization. > > Making it really hard and unnatural for people to use PHP enums as "cheap > named strings/ints" is something we want to keep, because the whole value of > enums is that they are their own separate type. A Direction is not a string, > it's not an int, it's not an array, it's not a Product, it's a Direction. > That's the end of it. Databases and HTML don't know from Direction or > Product, though, so it has to get serialized down to something for those. > For arbitrary objects, you basically have to write your own mechanism. (I > did.) For enums, one comes built-in to make it more standardized: backed > enums.
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. > > >> I'm not sure if I'd support it myself at the moment > > Noted, but I once again find myself needing to ask: why not? Were it up > > to me, I'd say let's start right now! :) > > Mainly because I haven't thought it through to see what possible issues it > could cause. It may be safe, or there may be currently-not-obvious issues > that would result. That's the sort of thing we'd need to explore. > > For instance, how useful would it be, given that the casing for an enum > should be CamelCase (per PER-CS), but the serialized string is most often > snake_case, and otherwise lowerCamel? We definitely cannot bake case folding > magic into the behavior. So is it even useful at that point? I don't know. > Maybe. That's what needs to be explored. I don't see how casing of the backed value is relevant. If you want it to be something different, then specify it in the class body. 9/10 of the time, you just need to serialize the enum somewhere and the casing doesn't matter. If it does matter, then specify the values manually. > > It's not something I'm planning to work on myself at this point, though if > someone else wanted to dig into it I'm happy to help brainstorm with them. > > --Larry Garfield