php-enum icon indicating copy to clipboard operation
php-enum copied to clipboard

Value-less enum

Open hikari-no-yume opened this issue 10 years ago • 6 comments

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?

hikari-no-yume avatar Jan 22 '15 11:01 hikari-no-yume

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…

mnapoli avatar Jan 30 '15 22:01 mnapoli

Yeah, the syntax is a bit iffy...

hikari-no-yume avatar Jan 30 '15 22:01 hikari-no-yume

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 avoid UnexpectedValueException 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.

mirfilip avatar Jan 30 '15 23:01 mirfilip

@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).

mnapoli avatar Jan 31 '15 00:01 mnapoli

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.

mirfilip avatar Jan 31 '15 13:01 mirfilip

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.)

MikkelPaulson avatar Jul 09 '20 19:07 MikkelPaulson