Hi David, On Thu, Jun 29, 2017 at 11:58 AM, David Rodrigues <david.pro...@gmail.com> wrote:
> > The `final` modifier would likely clash with property type definitions, > if those ever make it to the language. > > Still, a few pain-points remain: > > * References to properties (you cannot reference final properties > anymore, and that is effectively a BC break for anything using reflection > and closure scope binding) > > I don't know if I understand, but for properties you could redefine a > final property on constructor (as Java). https://pastebin.com/bTZcUT33 > No, the problem is following: class Foo { final public $bar = 'baz'; } $foo = new Foo; $bar = & $foo->bar; $bar = 'taz'; var_dump($foo->bar); This kind of ugly code will break. > * Arrays and resources as properties > > You can modify arrays or resources on final variables, since that you > don't modify the reference. https://pastebin.com/D38wL8x7 > That doesn't make it "final", although I get your point, and yes, it basically prevents decreasing the reference count on that particular property. I think this kills the usefulness of the feature, but it's indeed still useful. > > * Named (Factory) constructors > > I don't understand. > Relatively common pattern: class Foo { private final $bar; private function __construct() { /* hammertime */ } public static function create($something) : self { $instance = new self(); $instance->bar = $something; return $instance; } } See also http://verraes.net/2014/06/named-constructors-in-php/ > > * Property nullability - how do you define if a property was written to > the "last valid time" before freezing it > > Because PHP don't have support to "variable initialization" (eg. "$name;") > then you should only initializate it when you will write the initial (and > freezed) value. https://pastebin.com/Ua6DFUC1 > Got it, so a "first write" would be equivalent to a freeze operation? When do you seal the property if the value isn't overwritten? Would you disable default values for properties that are declared `final`? > > > * Unset properties and providing an alternative mechanism to > distinguish "uninitiated", "undefined" and "frozen" in he event of final > properties usage, without breaking current property access semantics > > It will be modified. Final variables still are a variable, but with the > status that "never change after initializate" (a flag). We can just > implement a new reflection method to properties to identify if it > isFinal(), or even for variables like "is_final($var)". By other side, this > last doesn't make sense because the final variable is just a "code > documentation" to the own dev knows that is not allowed modify it anymore. > Maybe we need implements that only for ReflectionProperty (first case), > because it could be part of a code that the user have not modify access > (eg. vendor code). https://pastebin.com/jSjNQACd > The reflection API is a given, but the problem is still the same: class Foo { private final $foo; private $lazyLoad; public function saySomething() { return 'Saying ' . $this->foo; } private function __construct() { } public static function new() : self { $instance = new self(); $instance->foo = 'something'; return $instance; } public static function newLazy() : self { $instance = new self(); $instance->lazyLoad = function () use ($instance) { $instance->foo = 'something lazy'; }; unset($instance->foo); return $instance; } public function __get($name) { ($this->lazyLoad)(); return $this->foo; } } $foo = Foo::new(); var_dump($foo->saySomething()); $lazyFoo = Foo::newLazy(); var_dump($lazyFoo->saySomething()); https://3v4l.org/UPVWF Hope that clarifies it. Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/