On 22/06/2022 18:26, Larry Garfield wrote:
The argument presented is that it's easier to type `AppRoles::Admin` than 
`"admin"`, because the former provides you with an error if you typo something. 
 That's a valid argument, but... not for using enums.  It's an argument for using 
constants.


I wonder if the reality is that neither enums (as implemented) nor constants are the right solution to to this.

What users want is some way to say "this value should be a string, but in this context it should be one of this list of strings"; or, sometimes, "is this string one of this list of strings?" Constants can't do that - they give you a way of referring to the possible values, but no tools for enforcing or testing against them. Backed enums can kinda sorta do that with a bit of effort, using ->value and ::tryFrom, but they're not really built for it.


A better fit would be some kind of "domain type", which would allow you to write something vaguely like this:

domain SymfonyPermission: string;
domain AcmePermission: string { 'admin' | 'user' | 'bot' };

assert( in_domain('admin', SymfonyPermission) );
assert( in_domain('admin', AcmePermission) );

assert( in_domain('random stranger', SymfonyPermission) );
assert( ! in_domain('random stranger', AcmePermission) );


Domains can also be considered sets, which you could compare directly, and maybe even calculate intersections, unions, etc:

assert( is_subset(AcmePermission, SymfonyPermission) );


The actual values would be ordinary strings, and type constraints would just be checking the value passed against the domain:

function doSymfonyThing(SymfonyPermission $permission) {
    echo $permission; // no coercion needed, $permission is a string
}

function doAcmeThing(AcmePermission $permission) {
    doSymfonyThing($permission);
}

doAcmeThing('admin'); // no special syntax needed to "construct" or "look up" an instance


Crucially, this solves the described problem of a library accepting an infinite (or perhaps just very wide) set of values, and a consuming app wanting to constrain that set within its own code.

It's one disadvantage is the typo-proofing and look up availability that constants give, but you could always combine the two.


Regards,

--
Rowan Tommins
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to