Am 05.12.20, 16:21 schrieb "Rowan Tommins" <rowan.coll...@gmail.com>:

    (Apologies if this posts twice, I may have accidentally hit send before 
    I'd finished writing it)


    On 05/12/2020 14:21, Marc Bennewitz wrote:
    > * Do cases have a stable ordinal number / position and is that accessible?
    >    This would be very interesting on implementing an optimized EnumSet 
using bit-array / bit-set internally

    If you want to associate a stable value with each case, you can use a 
    "primitive-equivalent enum" and assign each case an integer manually. As 
    the RFC says:

     > There are no auto-generated primitive equivalents (e.g., sequential 
    integers).


    I think that's a good design decision, because the language itself can't 
    actually guarantee a stable ordinal number if the enum's author makes 
    changes; e.g. given:

    enum Colour { case RED; case GREEN; case BLUE; }

    somebody might decide the cases should be in alphabetical order:

    enum Colour { case BLUE; case GREEN; case RED; }

    It seems unnecessarily confusing to have this be a breaking change 
    because code somewhere relied on the ordering. It's much clearer if the 
    author has to declare an intentional value, and can then maintain it 
    when making cosmetic changes to their own code:

    enum Colour { case BLUE=3; case GREEN=2; case RED=1; }


Sorry for the confusion - I mean stable within the same process - not over 
different processes / systems.


    > * I often use metadata in enumerations and so I would be very 
    > interested to allow constants.


    Could you give an example what you mean? Metadata on individual cases is 
    supported by methods, which map more cleanly to things like interfaces, 
    and the notion of each case as a singleton object, not a static class.


    That said, I have a related question: can enum cases be used as the 
    *value* of constants? e.g.:

    class OldMaid {
         public const SUIT = Suit::Spades;
         public const VALUE = CardValue::Queen;
    }


    If so, this leads to an interesting use case for constants on the enum 
    itself (not the cases) to define aliases:

    enum Suit {
       case Hearts;
       case Diamonds;
       case Clubs;
       case Spades;
       const Tiles = self::Diamonds;
       const Clovers = self::Clubs;
       const Pikes = self::Spades;
    }

    // The constants and cases can be used interchangeably, since constants 
    and cases are de-referenced with the same syntax
    assert(Suit::Spades === Suit::Pikes);


I mean on mapping something to something else defined as a single assoc array 
constant.
Something like:

enum Role {
  case User,
  case Admin,
  ...
}

enum Action {
  case Order_Edit,
  case Order_Read,
  
  private const BY_ROLE = [
    Role::User => [self::Order_Read],
    Role::Admin => [self::Order_Read, self::Order_Edit],
  ];

  public function isAllowed(User $user) {
    return in_array($this, self::BY_ROLE[$user->role]);
  }
}



    Regards,

    -- 
    Rowan Tommins (né Collins)
    [IMSoP]

    -- 
    PHP Internals - PHP Runtime Development Mailing List
    To unsubscribe, visit: https://www.php.net/unsub.php

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to