Skip to content

Not enough info on the difference between BuiltinEnum::coerce and as/?as #1368

@alexeyt

Description

@alexeyt

Please complete the information below:

Where is the problem?

https://docs.hhvm.com/hack/built-in-types/enum#is--as

What is the problem?

It says The operators is and as/?as behave similarly, but not exactly, to isValid() (similar to is) and assert()/coerce() (similar to as/?as) but does not explain what the difference in behavior is. The difference between coerce and as/?as is very important when values of the 'opposite' arraykey type to the base type of the enum may be present; for example:

<?hh

enum MyIntEnum: int {
   ZERO = 0;
   ONE = 1;
}

enum MyStringEnum: string {
  ZERO = '0';
  ONE = '1';
}

<<__EntryPoint>> function main(): void {
  echo "string values, int enum\n";
  var_dump(
    MyIntEnum::coerce('1'),
    '1' as MyIntEnum,
    '1' ?as MyIntEnum,
  );
  var_dump(
    MyIntEnum::ONE is int,
    '1' as MyIntEnum is int,
  );

  echo "int values, string enum\n";
  var_dump(
    MyStringEnum::coerce(1),
    1 as MyStringEnum,
    1 ?as MyStringEnum,
  );
  var_dump(
    MyStringEnum::ONE is string,
    1 as MyStringEnum is string,
  );
}

produces

string values, int enum
int(1)
string(1) "1"
string(1) "1"
bool(true)
bool(false)
int values, string enum
string(1) "1"
int(1)
int(1)
bool(true)
bool(false)

In light of this the wording Caution: These operators may perform implicit int/string coercion of enum values to preserve compatibility with isValid() seems potentially deceptive as well - when I first read it I assumed that the result of as/?as may be a different type from the input (what ::coerce() does). In reality coercion is done when checking if the value is compatible with the enum only; if it is then as/?as will pass it through un-coerced.


Please don't change anything below this point.


  • Build ID: HHVM=HHVM-4.164.0:HSL=v4.108.1:2024-02-08T13:44:46+0000:1fa47f258c6b68f8ec01899aa82fd6ffa0957109
  • Page requested: /hack/built-in-types/enum
  • Page requested at: Thu, 09 May 2024 21:00:36 +0000
  • Controller: GuidePageController

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions