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