Sorry, accidently sent in the middle of typing that...

On Wed, Mar 8, 2017 at 7:42 AM, Ryan Pallas <derokor...@gmail.com> wrote:

>
>
> On Wed, Mar 8, 2017 at 5:25 AM, Andrey Andreev <n...@devilix.net> wrote:
>
>> Hi all,
>>
>> I submitted a GitHub PR* to allow objects implementing __toString() to
>> *optionally* pass is_string() validation. More verbose wording of my
>> motivation can be seen in the PR description, but here are the main
>> points:
>>
>> - Simpler way to do checks like: is_string($var) ||
>> method_exists($var, '__toString')
>> - Can be used for stricter string parameter validation in
>> strict_types=0 mode (otherwise any scalar type is accepted)
>
> - Can be used for looser string parameter validation in strict_types=1
>> mode (__toString() objects aren't accepted there)
>> - Regardless of the last 2 points, it is intentionally not limited to
>> parameter types
>>
>
> If I understand correctly, you want the following to work:
>
> declare(strict_type = 0);
function foo(string $bar) {
    return $bar.'foo';
}

class Foo {
    private $val;
    public function __construct(string $val) {
        $this->val = $val;
    }
    public function __toString() {
        return $this->$val;
    }
}

echo foo(new Foo('this is ')); // this is foo

But what happens if I change the foo function like:
function foo(string &$bar) {
    $bar .= 'foo';
}

$foo = new Foo('object');
foo($foo);
var_dump($foo); // will this be an instance of Foo, or the string
"objectfoo"??

If $foo remains an object in this scope, then the function is not modifying
its value. If it becomes a string, it's an unexpected change IMO. It is
probably fine in this case, but not in the case of a more complex object.

>
>
>
>>
>> * https://github.com/php/php-src/pull/2408
>>
>> ---
>>
>> I didn't have time to write this email right after submitting the
>> patch, and in the meantime got some feedback from Fleshgrinder on
>> GitHub, which I'll quote and address here:
>>
>> > Thanks for your effort and initiative.
>> >
>> > However, I strongly believe that this is the wrong approach. Adding a
>> flag to a function directly results in the fact that the function violates
>> the single responsibility principle. What we actually need to make this
>> work is a "stringable" pseudo-type like the iterable type that was
>> introduced in PHP 7.1. This "stringable" pseudo-type is the union of the
>> scalar primitive string and any class that implements the __toString method.
>> >
>> > This has the advantage that we are actually able to use it together
>> with strict_types, plus we have separate dedicated functions like
>> "is_stringable" that adhere to the single responsibility principle. I
>> actually wanted to create an RFC for that along with an implementation
>> since iterable was accepted, but did not find the time yet.
>> >
>> > Closing note: these pseudo-types are necessary in PHP because it has no
>> coherent type system, and there is nothing we can do about this in short
>> term. Hence, adding such pseudo-types is the only short term solution that
>> we actually have.
>>
>> I ultimately wouldn't care if it's a separate function and did in fact
>> think of an is_stringable() function, but wasn't happy with the naming
>> - who's to say that e.g. integers aren't stringable? Bar
>> horribly-verbose names like
>> "string_or_objects_implementing__toString", I don't think there's a
>> way to avoid that ambiguity. :/
>> If we want a "stringable" type though, I guess we'll have to live with
>> that.
>>
>> I feel that debating the actual type system is way broader than I
>> intended this to be, so I'll refrain from going further on that for
>> now, as I've got some more radical ideas about it.
>>
>> ---
>>
>> Thoughts?
>>
>> Cheers,
>> Andrey.
>>
>> --
>> PHP Internals - PHP Runtime Development Mailing List
>> To unsubscribe, visit: http://www.php.net/unsub.php
>>
>>
>

Reply via email to