Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Value-less enum #7

Open
hikari-no-yume opened this issue Jan 22, 2015 · 6 comments
Open

Value-less enum #7

hikari-no-yume opened this issue Jan 22, 2015 · 6 comments

Comments

@hikari-no-yume
Copy link

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?

@mnapoli
Copy link
Member

mnapoli commented Jan 30, 2015

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…

@hikari-no-yume
Copy link
Author

Yeah, the syntax is a bit iffy...

@mirfilip
Copy link

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.

@mnapoli
Copy link
Member

mnapoli commented Jan 31, 2015

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

@mirfilip
Copy link

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.

@MikkelPaulson
Copy link

MikkelPaulson commented Jul 9, 2020

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants