-
-
Notifications
You must be signed in to change notification settings - Fork 66
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
Index support for enum values #10
Comments
PS: |
Here's the definition of enums in programming languages, according to Wikipedia:
I think this library does adhere to this definition: "a data type consisting of a set of named values". Furthermore, it is already possible to map integers to names values by using value methods: /~https://github.com/spatie/enum#enum-specific-methods While I get what you're saying, I think it misses the point of the package. The core idea behind it is to eliminate the inconsistency between the methods and constant values, as other enum packages do. I've explained this in detail here: https://stitcher.io/blog/php-enums I agree that I'll be closing the issue, but feel free to continue the conversation. |
Yes, the two definitions don't conflict - the programming one only misses the fact that the named values have a numerical counter part. Let's stick to your "perfect world" example:
If I convert it to this package it would be: /**
* @method static self DRAFT()
* @method static self PUBLISHED()
* @method static self ARCHIVED()
*/
class PostStatus extends Enum {} If I now call So yes, it's possible at the moment - but it isn't the default behavior. The default behavior is a limited string collection which are usable as string or object. So the default should return the index of the Also MySQL as a database which support enum keeps them as a string to array map. https://dev.mysql.com/doc/refman/5.7/en/enum.html I concede that the string return value works better with MySQL because there index starts with 1 and the recommendation is to use the string value instead of the index. |
We could add a numeric index. Though I'm unsure about enums being represented by their numeric value: it doesn't have any meaning. The status "draft" and its index "0" don't have meaning besides it's current position. Say we were to add another enum value two years after a project has been in production. Let's call it I know all of this is solvable, but at what cost? Do we really want this package to be this brittle? Do we want programmers to be concerned about breaking production every time they make such a trivial change? The only argument I can think of in favour of storing numeric indices is performance. But if your project is large enough for these kinds of things to become performance issues, I recon you won't have any problems with changing the default behaviour of this package. Please feel free to share your thoughts! I'm open to be proven wrong here. |
Like I said - if it comes to DB the current implementation works better
I haven't checked what MySQL uses under the hood, behind the strings it also stores tiny-ints, but I also don't know what happens if I add a new value to the MySQL enum. This would be a pretty good question.^^ The benefit of numerics is: performance, size, don't care about casing and option to compare/order them. My primary issue is more a conceptual and theoretical one - keep this Enum class as close as possible to a real enum. And a real enum would be something like: enum PostStatus {
DRAFT, PUBLISHED, ARCHIVED
}
PostStatus::DRAFT // 0
PostStatus::PUBLISHED // 1
PostStatus::ARCHIVED // 2 or with manual defined first index enum PostStatus {
DRAFT=2, PUBLISHED, ARCHIVED
}
PostStatus::DRAFT // 2
PostStatus::PUBLISHED // 3
PostStatus::ARCHIVED // 4 |
After a night and the fact that an userland Implementation should make things easier at first doesn't have to be 100% definition compliant I have an idea. The Atm I don't have an idea how to define a custom index via all options to define values. As doc-tag it's easy but via the |
I really appreciate you thinking along, thanks! Some more background information: the first implementation of this package supported the To be honest: I don't like I'm open for adding
Are you motivated to try and PR a solution? Otherwise I'll take a look at it somewhere in the next weeks, and we can review it together. |
No problem! :) Because of the fact that this would be BC at all we could also drop this variable. Something I would add as a constraint: you can't mix defined index and auto index. Or at least not without conflicts. Deserialization would be easy. For serialization you can use the methods |
I'm fine with dropping
That sounds good! |
What do you think about This would be more effort to write but allows to use the method description for what it's made for and follows official php-doc rules. The only con would be that it suggests the IDE and developer that there is an optional argument. |
I'm afraid it would be confusing to the developer though. As if you could pass another value to the
Maybe we should take a step back and ask ourselves how often a user would want to override the index? Wouldn't value specific anonymous classes suffice in those cases? Say we'd add a As always: I'm thinking aloud so feel free to say I'm wrong 😁 |
@brendt I 100% agree! During scribbling around I noticed that we have two ways, and will have to keep them, to declare values - doc-block & static method. And if we ask the question you've already opened
So far I'm the only one and so far I work with constants and a defined |
After an enum is "parsed", its contents are stored into
My first approach would be to add it in the constructor, we could use Overriding indices should be supported in $enumValues[$value] = $name; Would become something like: $enumValues[$enumValueDefinition->getIndex()] = $enumValueDefinition; Both |
As a sidenote: we could consider storing the enum value definitions in an array, instead of another object. Ideally we'd want to use a struct here, but we're still working with PHP, of course 😁 I'd consider using an array for performance reasons, though maybe a class with public properties is actually more performant than arrays... |
Let's re-open this issue btw, but I'm going to change to title to better reflect what it is about. |
enumerable
adjective
MATHEMATICS
This is the current definition of enumerable. The current Enum class does not implement this - it's only a string map. Instead it should be a map of strings to integers (positive).
So the current implementation should be changed at multiple points.
An idea would be to switch over to constants (key forced to be string and unique). While looping over all constants the value could be also checked for uniqueness.
The results of these reflection class operations could be cached in a static variable(s).
The definition of the class will also look more like an enum in this case.
Constants like
FOO_BAR
could be converted to lowerCamelCasefooBar()
.The usage could be
Days::monday()
to get a valued instance of the Enum.Days::from($day)->equals(Days::MONDAY)
or without type safetyDays::from($day) == Days::MONDAY
.Similar behavior is implemented in
SplEnum
http://php.net/manual/de/class.splenum.php without the other functionalities provided by this package.The text was updated successfully, but these errors were encountered: