RE: Accessors v2.4 Proposed Changes
| From: | Clint M Priest | Date: | Tue, 27 Mar 2012 13:30:22 +0000 |
| Subject: | RE: Accessors v2.4 Proposed Changes | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-59182@lists.php.net to get a copy of this message | ||
I haven't seen any other yeah/neigh comments about these changes, does everyone agree with
them?
-----Original Message-----
From: Clint M Priest [mailto:cpriest@zerocue.com]
Sent: Thursday, March 22, 2012 2:00 PM
To: internals@lists.php.net
Subject: [PHP-DEV] Accessors v2.4 Proposed Changes
I've been away from this for a while and getting back to it now... Wanted to open discussion
back up on these two points that Rasmus and Tom had:
1) Accessor should over-ride the __get()/__set(). If an accessor is set for a property, it
would be ineligible for calling __get/__set, anyone disagree?
2) Automatic backing fields should be protected and not public
Does anyone else have any comments about this RFC (as-implemented)?
https://wiki.php.net/rfc/propertygetsetsyntax-as-implemented
http://www.clintpriest.com/patches/php-core/accessors/2.4.diff
I'd like to get this slated for the next stage, presumably to be put into the core... What are
the next steps?
Thanks,
-Clint
From: Rasmus Schultz [mailto:rasmus@mindplay.dk]
Sent: Saturday, February 04, 2012 2:34 PM
To: Clint M Priest
Cc: internals@lists.php.net
Subject: Re: [PHP-DEV] Re: internals Digest 4 Feb 2012 09:08:29 -0000 Issue 2549
On Sat, Feb 4, 2012 at 1:13 PM, Clint M Priest <cpriest@zerocue.com<mailto:cpriest@zerocue.com>> wrote:
The read-only and write-only keywords act a little differently. Without them, attempting a set on
an accessor without a setter defined will cause __set() to be called whereas with the read-only it
will produce an error. The inverse is true for write-only. I attempted to keep the ability to
have lazy initializing of properties via accessors, but that could be written in php slightly
differently if the read-only/write-only keywords were not present (due to guards). Doesn't
particularly matter to me.
I'm hard pressed to think of a real use-case for something like that - seems like this could
easily cause confusion, having the getter invoke one mechanism, and the setter an entirely different
mechanism.
In my opinion, if you declare an accessor (whether get, set, or both) the accessor-mechanism should
take over and replace the "magic" methods. In the case of a read-only or write-only
accessor, I'd expect an exception, not a magic method as a secondary fall-back mechanism.
Accessor-methods aren't magic, they're concrete properties that execute code when you use
them. Accessors give you more compartmentalization than __get() and __set() which work for
"wild" property-names - e.g. in situations where you don't know at design-time
whether a property exists; but with accessors, you're defining concrete property-names, so
there is no need for "magic". In my opinion.
And then there's the matter of actually explaining the read-only and write-only keywords to
programmers, and the difference in behavior. This would be easier to explain, if the difference
wasn't almost a different language-behavior. Normally, public $foo prevents both __get() and
__set() being invoked for the $object->foo property - that's been a given for a long time,
and it's a mechanism that is easy to explain and easy to understand.
While you could certainly explain how this works, and I personally understood your explanation, as
said, it's very hard for me to think of a real use-case - so while you can make it understood
how this works, technically, it's unlikely that you, as a programmer, will ever actually care
or fully understand the differences until someday you run into it. It's less likely to be
something you look for to solve a particular problem - which means it's more likely to get in
the way.
Just my opinion :-)
> Would it not be more correct to implement an auto-backing field as
> protected? The reason for implementing accessors in the first place, is usually to prevent
> direct access to an underlying field.
Makes sense, in C# these backing fields are completely inaccessible directly, would that be even
better in this case or would protected suffice?
There are definitely situations (such as ORM) where you may need access to the backing-field...
It's a common requirement when, for example, the set-accessor has side-effects. A dirty-flag,
timestamp or version-number, for example - you don't want those invoked when the ORM hydrates
an object with database-values.
There are also cases when backing-fields get initialized at construction - when a class extends
another class, the enhanced constructor might need direct access to the backing-field.