Skip to content
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

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

Open
alexeyt opened this issue May 10, 2024 · 0 comments
Open

Comments

@alexeyt
Copy link
Contributor

alexeyt commented May 10, 2024

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
@alexeyt alexeyt changed the title Not enough info on the difference between BaseEnum::coerce and as/?as Not enough info on the difference between BuiltinEnum::coerce and as/?as May 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant