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 >