bwoebi · GitHub

I really like the direction this is going, as it matches the idea of how I'd have implemented it. I'd recommend one addition though, which I find make Java enums really powerful:

In Java, you have the possibility to define constructor arguments for each enum constant. These then get passed to a constructor, so your enum can hold more than just a simple scalar value. Going by their example, something like this could then be possible in PHP as well:

enum Planet
{
    MERCURY = (3.303e+23, 2.4397e6),
    VENUS = (4.869e+24, 6.0518e6),
    EARTH = (5.976e+24, 6.37814e6),
    MARS = (6.421e+23, 3.3972e6),
    JUPITER = (1.9e+27, 7.1492e7),
    SATURN = (5.688e+26, 6.0268e7),
    URANUS = (8.686e+25, 2.5559e7),
    NEPTUNE = (1.024e+26, 2.4746e7);
    /**
     * Universal gravitational constant.
     */
    private const G = 6.67300E-11;
    /**
     * Mass in kilograms.
     *
     * @var float
     */
    private $mass;
    /**
     * Radius in meters.
     *
     * @var float
     */
    private $radius;
    private function __construct(float $mass, float $radius)
    {
        $this->mass = $mass;
        $this->radius = $radius;
    }
    public function mass() : float
    {
        return $this->mass;
    }
    public function radius() : float
    {
        return $this->radius;
    }
    public function surfaceGravity() : float
    {
        return self::G * $this->mass / ($this->radius * $this->radius);
    }
    public function surfaceWeight(float $otherMass) : float
    {
        return $otherMass * $this->surfaceGravity();
    }
}

Also, I'm not sure I understand how you serialize enums right now. Are you storing the ordinal value of enum in the serialized string or the constant name?

Another thing I'd like to mention is that Java enums have a a few methods:

  • final public static function valueOf(string $name), which returns the enum of that name (or throws an exception if not exists)
  • final public static function values(), which returns an array containing all enum constants (say, instances)
  • final public function name() : string, which returns the name of the enum constant
  • final public function ordinal() : int, which returns the ordinal index of the constant in the definition
  • public function __toString() : string, which returns the string representation of the enum constant, which is the name by default, but this method can be overriden by the user

If I see your test codes directly, when comparing two enums of the same type, it actually compares the ordinal values of them, is that correct?

Last but not least, can a user extend a defined enum or is it's class representation marked as final? Otherwise, can the user mark it as final themself?

That's all I have for now :)

Read the original on github.com ↗