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:ras...@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 
<cpri...@zerocue.com<mailto:cpri...@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.

Reply via email to