Re: [IDEA] allow extending enum
| From: | Tim Düsterhus | Date: | Thu, 30 Mar 2023 18:19:19 +0000 |
| Subject: | Re: [IDEA] allow extending enum | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-119801@lists.php.net to get a copy of this message | ||
Hi
On 3/29/23 16:31, Davey Shafik wrote:
The issue of contention here is that inheritance isn't the correct mechanism for reusing enum definitions to expand on them. What about allowing "use" syntax like traits?
enum HttpErrors {
case HTTP_STATUS_400;
case HTTP_STATUS_401;
…
}
I understand that this is just an example, but I'd like to note that using an enum for HTTP status codes would likely be a misuse. Valid HTTP status codes are all three-digit numbers in 1xx to 5xx and HTTP error codes are everything 4xx and 5xx. HTTP status code are specifically designed for you to be able to handle them generically based on the first digit, even if you don't know about the specific code.
enum ApiErrors {Including all the cases of another enum is not unlikely to result in conflicts, because the enum name effectively acts as a namespace with regard to the enum cases. Staying with the HttpErrors enum for sake of the example, you'd rather useuse HttpErrors;case JsonParserError; case GraphQLParserError;} Now you have ApiErrors::HTTP_STATUS_400 etc without ApiErrors being is-a HttpErrors.
case Forbidden instead of case HTTP_STATUS_403, because HttpErrors::HTTP_STATUS_403 redundantly includes the 'HTTP'. Mark's example of DatabaseError would possibly also have a case Forbidden in case your database password is incorrect or in case you may not access the queried table or whatever.
Instead it would likely be preferable to get tagged unions (https://wiki.php.net/rfc/tagged_unions) and then nest the errors, like commonly done in Rust:
enum ApiErrors {
case HttpRequest(HttpErrors $httpError);
case JsonParsing;
case GraphQlParsing;
}
And then $foo = ApiErrors::HttpRequest(HttpErrors::Forbidden);. The Exception equivalent would be leveraging the $previous value to provide the context.
Best regards
Tim Düsterhus