php-enum
php-enum copied to clipboard
Value-less enum
Here's another idea:
Perhaps a variant of this class which doesn't have a value for each enum member, so SomeEnum::FOO
doesn't work but SomeEnum::FOO()
does? Could be used like so in PHP 5.6:
class SomeEnum extends ValuelessEnum
{
const _values = ['FOO', 'BAR', 'QUX'];
}
Or something like that. Maybe not a good idea. What do you think?
I like the feature idea. I'm not so sure about the suggested implementation though, it's really not consistent with the current "syntax".
IMO it's not a big deal to give values 1, 2, 3, … Especially since I often find that the 0
case needs to be handled with care (because it can be confused with null
): sometimes it needs to start with 1, sometimes 0 is fine…
Yeah, the syntax is a bit iffy...
The idea is very valid. @mnapoli the argument that you have to handle your values with care kinda defeats the purpose of enums (as they are defined e.g. in Java).
The implementation as I'd see it:
- Values are stored under private member instead of consts. If you want to get list of all options, use
toArray()
- There is a private member _value (or sth like that) which holds the chosen value. If you want to create the instance of enum with chosen value, you go
SomeEnum::FOO()
, which uses__callStatic()
. You can still use @method phpdoc to hint at all possible values. - You can still go
new SomeFoo('FOO')
. That one is optional, cause in order to avoidUnexpectedValueException
you'd have to specify the argument string correctly.
It's totally doable, but the structure would have to change a bit (because this version wouldn't have a notion of keys and values). If you like my view of it, I think I could have a shot in couple of days.
@mnapoli the argument that you have to handle your values with care kinda defeats the purpose of enums
Very true, my argument was more of "the gain/cost ratio is not really high, so I'd rather favor consistency". In a "true" enum implementation you are right values are optional.
The private $FOO
solution is an alternative indeed, but:
- it breaks BC: we could consider a new major version but is that really worth it? it works pretty well today, the library is being used a lot… All that to avoid having values. Again, benefit/cost ratio.
- even if we kept BC with the current way, it would mean 2 ways of defining enums. For something so simple as that, is that worth it? Meh. Never had a problem with the current way.
I think the most gain we could get would be to have a native PHP implementation (hint hint @TazeTSchnitzel :p).
Surely, ValuelessEnums
would break BC. If anything, it'd be a same level class but completely separate from Enum
. IMO, not worth it as well. The idea with singletons is way more attractive.
This is doable with the existing implementation, if you take advantage of constant scopes:
class MyEnum extends Enum
{
protected const FOO = 'FOO';
}
MyEnum::FOO(); // works
MyEnum::FOO; // Fatal error: Uncaught Error: Cannot access protected const MyEnum::FOO
Your enum still technically has a value, but the value is explicitly defined as an implementation detail rather than exposed as relevant to the rest of the application. (A further enhancement could return null or throw an exception on getValue()
, __toString()
, etc. if the constant is protected, but I'm not sure what benefit that would provide.)