simonhamp,
@simonhamp@phpc.social avatar

Hey folks 👋🏼 got a little twisty thing to noodle on:

If a class and an enum can equally implement an interface, does that mean it's safe to use them interchangeably when your method type-hints the interface that they both implement?

🤔

Crell,
@Crell@phpc.social avatar

@simonhamp Yep. A type def for an interface will accept an object or enum that implements that interface just as well.

Enums are literally objects with funny syntax and a few blocked features.

simonhamp,
@simonhamp@phpc.social avatar

@Crell it's that funny syntax a d blocked features I'm worried about... like there might be some hidden edge-cases where if I assume it's a class and behaves like a class but I've got an enum and for some reason it doesn't behave the way I expect

I'm honestly struggling to think of a solid example, but I can't shake the thought that it's a possibility... I just haven't encountered it yet

cabbey,
@cabbey@phpc.social avatar

@simonhamp @Crell I would wager that any such use, with a class or an enum, would be a violation of the interface. The contract in the interface is all you are promised. Nothing more.

simonhamp,
@simonhamp@phpc.social avatar

@cabbey @Crell the only problem case I can see—and why I've decided against using the same interface on my enum as I would on a normal class—is the lack of support for clone

There will be some cases where it is necessary to clone the given object... if it's an enum, that's not possible

Unfortunately, the contract of the interface doesn't protect us there

Crell,
@Crell@phpc.social avatar
Crell,
@Crell@phpc.social avatar

@simonhamp @cabbey If your API design specifically depends on cloning, then yes, enums won't work. In practice, though, I find that unusual. Enums are value objects without associated values. It's like trying to clone the number 5.

dantleech,
@dantleech@fosstodon.org avatar

@Crell @simonhamp @cabbey I used an interface on an enum this one time which had __toString. That didn't work because __toString doesn't work on enums. Interface in question was for colors so __toString pretty printed it.

simonhamp,
@simonhamp@phpc.social avatar

@dantleech @Crell @cabbey I guess that’s an even more common example

I guess the approach to that though would be to make your interface require an explicit toString method that you must implement in your enum

But maybe there's also case for an RFC to add __toString() support to enums?

dantleech,
@dantleech@fosstodon.org avatar

@simonhamp @Crell @cabbey yeah the use of __toString is questionable. I was using it as a "debug representation" method. It was deliberately not supported on enums for reasons.

Crell,
@Crell@phpc.social avatar

@dantleech @simonhamp @cabbey If you want debugging, __debugnfo(): https://www.php.net/manual/en/language.oop5.magic.php#object.debuginfo

Hm, though that seems blocked on enums, too. That may make sense to unblock, maybe? Though an enum's var_dump() output is already pretty self-explanatory.

dantleech,
@dantleech@fosstodon.org avatar

@Crell @simonhamp @cabbey that returns an array tho. this is "format this object as a string in a human way" for logging, debugging, whatever... and tbh I don't even care about casting to string. But somehow the ubiquitousness of __toString() and made it appealing for this case.

cabbey,
@cabbey@phpc.social avatar

@dantleech @Crell @simonhamp couldn’t you just put the pretty print version as the backing value? Or did you have something else there?

dantleech,
@dantleech@fosstodon.org avatar

@cabbey @Crell @simonhamp the use case was having an enum with a set of named colors and a class for RGB colors, in Rust they'd both be Enums...

Crell,
@Crell@phpc.social avatar

@simonhamp It's all stuff that would be syntactically within the enum.

There's a doc page specifically on it: https://www.php.net/manual/en/language.enumerations.object-differences.php

simonhamp,
@simonhamp@phpc.social avatar

@Crell Ah! Excellent! Thanks for digging that out

This helps immensely and has made me clearer on my decision already 🙏🏼

  • All
  • Subscribed
  • Moderated
  • Favorites
  • php
  • DreamBathrooms
  • magazineikmin
  • ethstaker
  • InstantRegret
  • tacticalgear
  • rosin
  • love
  • Youngstown
  • slotface
  • ngwrru68w68
  • kavyap
  • cubers
  • thenastyranch
  • mdbf
  • provamag3
  • modclub
  • GTA5RPClips
  • normalnudes
  • khanakhh
  • everett
  • cisconetworking
  • osvaldo12
  • anitta
  • Leos
  • Durango
  • tester
  • megavids
  • JUstTest
  • All magazines