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/

Reply via email to