On Fri, 22 Mar 2024, at 12:58, Robert Landers wrote:
> 
>> $optionalExpiryDateTime = $expiry as ?DateTimeInterface else new 
>> DateTimeImmutable($expiry);
> I'm not sure I can grok what this does...
>
> $optionalExpiryDateTime = ($expiry === null || $expiry instanceof
> DateTimeInterface) ? $expiry : new DateTimeImmutable($expiry)

Trying to write it as a one-liner is going to make for ugly code - that's why 
I'd love to have a new way to write it! But yes, that's the right logic.

With the "is" operator from the Pattern Matching draft, it would be:

$optionalExpiryDateTime = ($expiry is ?DateTimeInterface) ? $expiry : new 
DateTimeImmutable($expiry);

But with a clearer assertion that the variable will end up with the right type 
in all cases:

$optionalExpiryDateTime = $expiry as ?DateTimeInterface else 
some_other_function($expiry);
assert($optionalExpiryDateTime is ?DateTimeInterface); // cannot fail, already 
asserted by the "as"


> Maybe? What would be the usefulness of this in real life code? I've
> never written anything like it in my life.

I already explained the scenario: the parameter is optional, so you want to 
preserve nulls; but if it *is* present, you want to make sure it's the correct 
type before proceeding. Another example:

// some library function that only supports strings and nulls
function bar(?string $name) {
    if ( $string !== null ) ...
    else ...
}
// a function you're writing that supports various alternative formats
function foo(string|Stringable|int|null $name = null) {
    // we don't want to do anything special with nulls here, just pass them 
along
    // but we do want to convert other types to string, so that bar() doesn't 
reject them
    bar($name as ?string else (string)$name);
}


To put it another way, it's no different from any other union type: at some 
point, you will probably want to handle the different types separately, but at 
this point in the program, either type is fine. In this case, the types that 
are fine are DateTimeInterface and null; or in the example above, string and 
null.


> $optionalExpiryDateTime = $expiry == null ? $expiry : $expiry as
> DateTimeInterface ?? new DateTimeImmutable($expiry as string ?? "now")

If you think that's "readable" then we might as well end the conversation here. 
If that was presented to me in a code review, I'd probably just write "WTF?!" 

I have no idea looking at that what type I can assume for 
$optionalExpiryDateTime after that line, which was surely the whole point of 
using "as" in the first place?

Regards,
-- 
Rowan Tommins
[IMSoP]

Reply via email to