Hey Tim, On Thu, Jan 12, 2017 at 10:51 PM, Tim Bezhashvyly <tim.bezhashv...@gmail.com > wrote:
> Hi Richard, > > thank you for support with __construct. I absolutely agree that it breaks > BC and fine to propose it just for PHP 8. > > By polymorphic dispatch I mean a possibility to have the same method > (including constructor) in multiple variations. E.g.: > > class Price > { > public function __construct(int $price) > { > ... > } > > public function __construct(string $price) > { > ... > } > } > > Regards, > Tim > > > On 12 Jan 2017, at 22:39, Fleshgrinder <p...@fleshgrinder.com> wrote: > > > > On 1/12/2017 10:13 PM, Marco Pivetta wrote: > >> Hey Richard, > >> > >> I made an example where everything was in a single class, but most > >> scenarios involve a lazy-loading wrapper that has no knowledge of the > >> original class besides its constructor. > >> > >> I use this approach to generate proxy classes that are "safe" to use > with > >> fluent interfaces, for example (because fluent interfaces are really a > mess > >> to work with). > >> > >> The alternative (for me, specifically) is to copy the constructor AST > into > >> a closure, then store the closure somewhere. Still, if that closure also > >> calls the private constructor, I have to do it recursively, and so on > until > >> I just give up :-P Also, this assumes codegen. Large pieces of code will > >> need rewriting, whereas I don't see strong reasoning for dropping a > feature > >> that, while weird, is actually useful. > >> > >> Marco Pivetta > >> > > > > That actually calls out for reflection and that's what it is good for. > > Even if explicit construct calls are to be forbidden, the reflection API > > is definitely a different story. > > > > That being said, your remarks definitely tell everyone that a change in > > this area -- if wanted -- is only possible in PHP 8 and has to be > > considered a breaking change. > > > > ``` > > <?php > > > > final class DbConnection { > > > > private $dsn; > > > > private $initializer; > > > > public function __construct($dsn) { > > $this->dsn = $dsn; > > // socket stuff happens here, much like with PDO > > } > > > > public static function lazyInstance($dsn) { > > $reflector = new ReflectionClass(self::class); > > $self = $reflector->newInstanceWithoutConstructor(); > > $new = $reflector->getConstructor(); > > > > $self->initializer = function () use ($self, $new, $dsn) { > > $new->invoke($self, $dsn); > > $self->initializer = function () {}; > > }; > > > > return $self; > > } > > > > public function query($queryString) { > > $this->initializer->__invoke(); > > > > // irrelevant from here on > > return ['query' => $queryString, 'dsn' => $this->dsn]; > > } > > > > } > > > > $instance = DbConnection::lazyInstance('mysql://something'); > > > > var_dump($instance); > > > > var_dump($instance->query('SELECT * FROM foo')); > > var_dump($instance->query('SELECT * FROM bar')); > > ``` > > > > On 1/12/2017 10:34 PM, Tim Bezhashvyly wrote: > >> the only reason for prohibiting explicit __construct calls is that it > >> makes PHP objects mutable and it's state unpredictable. Still would > >> like to give this RFC a try. > >> > > > > I completely share this concern with Tim. Of course reflection would > > still allow one to circumvent any limitations imposed by the normal > > runtime. But that's what reflection is for after all. > > > > On 1/12/2017 10:34 PM, Tim Bezhashvyly wrote: > >> And what about polymorphic dispatch? > >> > > > > I think you need to elaborate a bit more here to get some feedback. > > > > -- > > Richard "Fleshgrinder" Fussenegger > > That's generally understood as "Method overloading". There were more discussions about it in here recently: you might want to look them up. Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/