On 3/8/2017 5:50 PM, Ryan Pallas wrote: > On Wed, Mar 8, 2017 at 9:50 AM, Ryan Pallas <derokor...@gmail.com> wrote: > >> >> >> On Wed, Mar 8, 2017 at 8:51 AM, Fleshgrinder <p...@fleshgrinder.com> wrote: >> >>> Hey! :) >>> >>> The reference is actually not a problem for a Stringable because you >>> would get the "Only variables can be passed by reference" error with an >>> object if `strict_types` is enabled. >>> >>> Simply because the object **MUST** be converted into a string. The >>> object itself does not satisfy the constraint, but the object clearly >>> states that it can be converted into a string at any point. >>> >> >> This is the part I disagree with. The object clearly states that it can be >> turned into a string when you are done using it as a object. If it gets >> turned into a string, you can no longer use it as a object. >> >> There is a difference between changing an int to string and an object to >> string, in that afterwards the int->string can continue to be treated as an >> int afterwards, thanks to loose typing (otherwise it wouldn't have become a >> string in the first place). However with an object->string afterwards it >> can ONLY be treated as a string, it can no longer be treated as an object. >> Meaning >> >> $int = 3; >> foo(3); >> > Sorry this should have been: > foo($int); > >> var_dump(++$int); // 4, success, no errors >> >> $obj = new Foo('a'); >> foo($obj); >> var_dump($obj->method()); // Fatal error: call to member function method >> on string. >> >> To me, this doesn't make sense. >> >>> >>> Not doing so would violate what `strict_types` actually promise us. ;) >>> >>> -- >>> Richard "Fleshgrinder" Fussenegger >>> >> >> >
function foo(string &$s) { $s = 'foo'; } final class Stringable { public function __toString() { return 'stringable'; } } $stringable = new Stringable; foo($stringable); // Fatal error: Only variables can be passed by reference in ... $string = (string) $stringable; foo($string); // Heureka! Why is that? At the point where we reach the call `foo($stringable)` we need to perform various checks, which will lead to the conclusion that we require a string and that the value of `$stringable` is an object that can be converted to a string. That is exactly what we do. Hence, the call is not `foo($stringable)` but rather `foo('stringable')`, the value that we received from the conversion. The conversion is in place, just like a cast would be, hence ... foo((string) $stringable); ... is equivalent to ... foo($stringable); ... with a type constraint of string for that particular argument. Obviously we should yield another error message in such cases, to ensure that people are not confused. However, this is only about the logic. This means by implication that a ... function foo(stringable &$s) { } ... is impossible. Something we encounter a lot lately with many features that we would like to have. This is also one of the reasons why many higher languages do not support pointers in their type systems. -- Richard "Fleshgrinder" Fussenegger -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php