Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:123395 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id E076C1A009C for ; Wed, 22 May 2024 00:48:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1716338987; bh=/LBz1J0OG1qtD5TiByqAKEHe6Ijx0WQCX3CkP37ZI1s=; h=From:Subject:Date:References:To:In-Reply-To:From; b=TPkSFgTZecYoSaiGNuj0Wkkmpi/gEwkYDMAJL75x75s0VOydcGqZhQz8wn7Jq1GCT CvngM+cWdwtLuFvFEvRiHWZYwlt+5OcuawaQCAxua3Ql2Fk6URw3gMpHYIE1qe4qoW CBBdCB/U9ZQPtMUIARM/cl1P28bEHvAb/Hxx0qjpLkgho11SW94Hr4002ueC8JnAcI RkNlzGkkQe6QW90DCAUxsVTXeYnis7i19g0NIOXkdVWAYwG3hayy2geQv7FtpJaZZa Wh+0/hM6F9gXZkrddTylrjJJbQAy1+sS9Eu5VzgFPrQ5eXSKDRO1JLmAg7yiQavR84 gLm9JMKNdBAgA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 444041801EE for ; Wed, 22 May 2024 00:49:45 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,HTML_MESSAGE, SPF_HELO_PASS,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from trowski.net (trowski.net [162.213.173.168]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Wed, 22 May 2024 00:49:42 +0000 (UTC) Received: from smtpclient.apple (unknown [10.0.1.105]) by trowski.net (Postfix) with ESMTPSA id 7D8821244D10 for ; Tue, 21 May 2024 19:48:02 -0500 (CDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/simple; d=trowski.com; s=mail; t=1716338884; bh=CPy7jWV7YxvMVylTeZ+YIP1O/Iw=; h=From:Subject:Date:References:To:In-Reply-To; b=ujgItNeAepuWwNOIiekzwDA9W5c2yK6mdmFD6iKpqox9lb8HvGgVbuTWALho8cgDD rjVjCwIryaRZZnPuMC74BVHCkzGOAvMNwI/Q+p0p+or+UHRvKJXyDx6BOIA9e5C1uw qoO3f/Bci7z5PMrjJdKgY4agzxS86M3B5fZT3fYMEq9x5WiVei1WmGrTNXx36yadz0 Bx23oizjQ/0W9d7pU9hnw3Zsk6QnjRoKh/hupDdHWJThYNH6w8wVfsv7GsKszaWw4k 6Bpg+mP64mIS+sKf69qb00Fancsyb6Z5WRWsaQffCyNyRBZ2QdwmdLojlFPJCU2fa6 dOUth0Y0EHqdw== Content-Type: multipart/alternative; boundary="Apple-Mail=_6B2C0306-FBEA-4069-94C3-2CC6D13CAF70" Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3774.400.31\)) Subject: Re: [PHP-DEV] [Discussion] Implicitly backed enums Date: Tue, 21 May 2024 19:48:00 -0500 References: <99c30f5d-e2f3-4027-a8fc-b3b9c71fb6d1@scriptfusion.com> <1286eed1-c35e-40ec-a6f0-84926c99c911@app.fastmail.com> <3cac0454-ceb2-449a-8b9a-1fac3f866a9c@scriptfusion.com> To: PHP Internals In-Reply-To: <3cac0454-ceb2-449a-8b9a-1fac3f866a9c@scriptfusion.com> Message-ID: <8D146901-ADF1-4BAA-B6AA-2CCCFE7A0158@trowski.com> X-Mailer: Apple Mail (2.3774.400.31) From: aaron@trowski.com (Aaron Piotrowski) --Apple-Mail=_6B2C0306-FBEA-4069-94C3-2CC6D13CAF70 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On May 21, 2024, at 6:47=E2=80=AFPM, Bilge = wrote: >=20 > On 22/05/2024 00:31, Larry Garfield wrote: >> I could see an argument for auto-populating the backing value off the = enum name if it's not specified, something like this: >> enum Options: string { >> case First; // This implicitly gets "First" >> case Second =3D '2nd'; >> } > This seems like a reasonable compromise. In this case, all I need to = do is change my enum to a backed enum (suffix `: string`) and I get the = benefits of implicit values. I still like the idea of the same being = possible for non-backed enums, though I imagine that is a product of my = na=C3=AFvet=C3=A9, as I do not tend to think of things in the framing of = (de)serialization. >=20 >> I'm not sure if I'd support it myself at the moment > Noted, but I once again find myself needing to ask: why not? Were it = up to me, I'd say let's start right now! :) >=20 > Aside, I am not at all concerned with integer-backed enums at this = juncture, and presume that could be a separate discussion/implementation = anyway. >=20 > Cheers, > Bilge >=20 As a workaround, you can use something like the trait below. ``` trait SerializableEnum { public readonly string $name; /** @return list */ abstract public static function cases(): array; public function toString(): string { return $this->name; } public static function from(string $name): self { return self::tryFrom($name) ?? throw new ValueError(sprintf( '"%s" is not a valid backing value for enum %s', $name, self::class, )); } public static function tryFrom(string $name): ?self { foreach (self::cases() as $case) { if ($case->name =3D=3D=3D $name) { return $case; } } return null; } } enum ExampleEnum { use SerializableEnum; case ONE; case TWO; case THREE; } var_dump(ExampleEnum::from('ONE')); var_dump(ExampleEnum::from('FOUR')); ``` Perhaps not as clean and easy as the functionality being built-in, but = it gets the job done. :-D Aaron Piotrowski --Apple-Mail=_6B2C0306-FBEA-4069-94C3-2CC6D13CAF70 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8
On May 21, = 2024, at 6:47=E2=80=AFPM, Bilge <bilge@scriptfusion.com> = wrote:

=20 =20
On 22/05/2024 00:31, Larry Garfield wrote:
I could see an argument for = auto-populating the backing value off the enum name if it's not = specified, something like this:
enum Options: string {
  case First; // This implicitly gets "First"
  case Second =3D '2nd';
}

This seems like a reasonable compromise. In this = case, all I need to do is change my enum to a backed enum (suffix `: string`) and I get the benefits of implicit values. I still like the idea of the same being possible for non-backed enums, though I imagine that is a product of my na=C3=AFvet=C3=A9, as I do not tend to think of = things in the framing of (de)serialization.

I'm not sure if I'd support it myself at the moment

Noted, but I once again find myself needing to ask: = why not? Were it up to me, I'd say let's start right now! :)

Aside, I am = not at all concerned with integer-backed enums at this juncture, and presume that could be a separate discussion/implementation anyway.

Cheers,
Bilge

As a workaround, you can use something like the = trait below.

```
trait = SerializableEnum
{
    public readonly = string $name;

    /**  @return = list<self> */
    abstract public static = function cases(): array;

    public = function toString(): string
    {
  =       return $this->name;
    = }

    public static function = from(string $name): self
    {
  =       return self::tryFrom($name) ?? throw new = ValueError(sprintf(
            = '"%s" is not a valid backing value for enum %s',
    =         $name,
        =     self::class,
        = ));
    }

    = public static function tryFrom(string $name): ?self
  =   {
        foreach (self::cases() as = $case) {
            if = ($case->name =3D=3D=3D $name) {
        =         return $case;
      =       }
        = }

        return = null;
    = }
}

enum = ExampleEnum
{
    use = SerializableEnum;

    case = ONE;
    case TWO;
    case = THREE;
}

var_dump(ExampleEnum::from('ON= E'));
var_dump(ExampleEnum::from('FOUR'));
```

Perhaps not as clean and easy as the functionality = being built-in, but it gets the job done. = :-D

Aaron = Piotrowski

= --Apple-Mail=_6B2C0306-FBEA-4069-94C3-2CC6D13CAF70--