On Wed, Jan 23, 2013 at 9:03 AM, Anthony Ferrara <ircmax...@gmail.com>wrote:

> Sherif,
>
>
> Don't get me wrong, I liked it, but I also disliked the fact that it
>> introduces language changes that aren't easy to grasp or document. To me
>> this means we've borderline changed the behavior of a property (which most
>> PHP users currently understand to be a variable) into potential methods.
>> This is basically saying we can now completely change the behavior of a
>> property from a storage unit to a functional unit. That's a bit of a scary
>> thought to me, because it makes me question everything I know about
>> properties in PHP.
>>
>
> Except that everything that's proposed here is possible today with __get,
> __set, __isset and __unset. So already today you can't assume that a
> property is a "variable". In fact, you could build something like this
> using __get, etc extremely dirty:
>
> class Foo {
>     public function __get($name) {
>         $method = 'get' . ucfirst($name);
>         if (method_exists($this, $method)) {
>             return $this->method();
>         }
>         return $this->$name; // public properties
>     }
>     public function __set($name, $value) {
>         $method = 'set' . ucfirst($name);
>         if (method_exists($this, $method)) {
>             return $this->method($value);
>         }
>         return $this->$name = $value; // public properties
>     }
> }
>
> The difference in functionality that this provides is the ability to
> custom-scope getters and setters. And it's a LOT cleaner...
>

This is not true. Magic getters and setters make a distinction that
accessors do not. That distinction is that they can only work on
inaccessible properties. Accessors offer no such distinction. They are
explicitly defined and as such their properties are not magical even though
they provide somewhat magical characteristics.

When you use var_dump to debug the property of an object, or the object
itself, for example, you would expect that whatever value is returned for
that property is either stored in memory somewhere or is the result of a
magic getter. Now, if it is the result of a magic getter there is no
confusion between whether this is an actual property or magic getter,
because a look at var_dump of that object tells us the whole story.

With accessors you now make the case that the property can be the result of
any computation and as such var_dump only reveals the underlying storage
unit and has no awareness of any computation.

class foo {
    public $bar {
        get() { return 'baz'; }
    }
}

var_dump(json_encode(new foo),new foo, (new foo)->bar);

// gives us
string(12) "{"bar":null}"
object(foo)#1 (1) {
  ["bar"]=>
  NULL
}
string(3) "baz"


There's a subtle difference here that's not obvious at first. The
difference is that we have no way of knowing whether "bar" is the result of
an accessor or a an actual property without closely examining the code.
There's no easy way to debug who went wrong when this causes a problem. If
the property is now acting as a method we have to start treating it like a
method in order to debug it. That could mean backtraces, exception
handling, and a variety of other things that I really find weird to have to
do with an a property.


Now, let's examine the alternative. Using magic methods...

class foo {
    private $bar;
    public function __get($name) {
        if ($name == 'bar') {
            return 'baz';
        }
    }
}

var_dump(json_encode(new foo),new foo, (new foo)->bar);

string(2) "{}"
object(foo)#1 (1) {
  ["bar":"foo":private]=>
  NULL
}
string(3) "baz"


At least here we know that "bar" is undoubtedly a private property so
whatever we got from (new foo)->bar must be the result of a magic getter.
There's only one place to look for that (in the magic method). With an
accessor I could easily create a situation where a bug manifests itself
anywhere in the code and not necessarily in the accessor itself that
accessor effectively becomes a method that does computation rather than
handling mere storage and retrieval.

I really really feel this is a way to give users lots of rope to hang
themselves with and at the cost of added complexity. I'm just not sure I
buy it. Sorry.


Sherif,
Arbiter of null.


> Anthony
>

Reply via email to