Yes, I'm aware - I thought of the clash with Nikita's proposal while
writing mine, but decided not to bring it up. If we were to go with my
proposed syntax, then one of two things would have to happen.
1) Don't auto implement get/set. *On a similar note, what's the difference
between using a property accessor that auto implements get/set* and a
normal property?
2) As you said, differentiate between get; and get();. The issue this
creates is obvious, and in my opinion this isn't a viable solution.

For the record, *read_only* and even moreso *readonly* are, in my opinion,
nicer than *read-only*.

On Tue, Oct 16, 2012 at 5:10 AM, Clint Priest <cpri...@zerocue.com> wrote:

>  This would conflict with the concept of auto-implementation, which if we
> went with Nikita’s suggestion, would make an undefined body setter actually
> set the property it shadows.****
>
> ** **
>
> For example ****
>
> ** **
>
> class a {****
>
>                 public $prop {****
>
>                                 get() { … }****
>
>                                 final set($x); ****
>
>                 }****
>
> }****
>
> ** **
>
> Would have final set() translate to final set($x) { $this->prop = $x; }***
> *
>
> ** **
>
> We **could** have it be that final set; or final set(); ß Without the ()
> or without the ($x) specifically mean that it is read-only but the clarity
> goes WAY down.  It is not at all intuitive that any of those things means
> ‘read-only’****
>
> ** **
>
> Why is everyone so against the two new keywords?  I’m told there has been
> talk long ago about having them as keywords anyway.  Is it the dash?****
>
> ** **
>
> Is this more palatable?****
>
> ** **
>
> public readonly $prop { ****
>
>                 get() { }****
>
> }****
>
> ** **
>
> Or****
>
> ** **
>
> public read_only $prop { … }****
>
> ** **
>
> Specifically, read-only actually has the advantage that one of the few
> ways that it would break BC is if someone had defined a variable named
> $read and attempted to subtract a constant or string of ‘only’ from it.***
> *
>
> ** **
>
> $read = 5;****
>
> echo $read-only;             // Yields 5****
>
> ** **
>
> with define(‘only’, 2);****
>
> ** **
>
> echo $read-only;             // Becomes 3****
>
> ** **
>
> I find it highly unlikely that someone would have been using $read-only or
> $write-only since variables cannot have dashes in them, he interpreter sees
> that as a subtraction and as shown above it would be nonsensical to have
> written PHP like that.****
>
> ** **
>
> ** **
>
> *From:* Jazzer Dane [mailto:tbprogram...@gmail.com]
> *Sent:* Tuesday, October 16, 2012 6:45 AM
> *To:* Clint Priest
> *Cc:* Stas Malyshev; internals@lists.php.net
> *Subject:* Re: [PHP-DEV] [PHP-DEV [RFC] Property Accessors v1.2****
>
> ** **
>
> private final get/set() {} is indeed not a read/write only functionality.
> I really would like to keep new keywords out of whatever syntax is
> implemented, but I think the latest proposal can and should be improved
> upon.
>
> I've been thinking about this quite a bit.
> To reiterate the initial problem, although we can disable get/set by not
> including it in the accessor, the reason we need read/write only is,
> without it, there is no way to not allow subclasses to add set/get to their
> parent's accessor.
>
> Going with the idea that not including get/set disables them, what about
> this syntax:****
>
> class MyObject
> {
>   public $property {
>     get() { ... }
>     final set; // Defining an accessor function without body is virtually
> the same as not defining the accessor function at all, i.e. this property
> accessor can not be set.
>   }
> }
>
> $object = new MyObject();
> $propertyValue = $object->property; // Works
> $object->property = 10; // Does not work, set not allowed****
>
>
> By "disabling" accessor functions that don't provide a body, we can easily
> imitate read/write arguably better than what the current RFC is capable of,
> and use exceptions that already exist (same as the exception thrown if the
> accessor function is never defined in the property accessor).****
>
> On Tue, Oct 16, 2012 at 4:19 AM, Clint Priest <cpri...@zerocue.com> wrote:
> ****
>
> Hey Stas, a bunch of this has already been covered but I will attempt to
> answer each of these as is my current understanding of "the hives"
> decision... :P****
>
>
> > 1. Accessors IMO should be regular PHP methods that PHP generates with
> two additional things:
> > a. Their name is generated by PHP
> > b. Their argument set is defined by the accessor pattern (i.e. same
> thing as __get/__set).
> > We should keep the amount of magic and special cases to the minimum, the
> engine is complex enough as it is.
> > This of course includes the full range of options available for the
> methods - final, reflection, call scenarios, etc.****
>
> This is the way it is, though Nikita strongly disagrees that they should
> be "callable, visible" methods on the object and I agree with Nikita on
> this issue, I never did like the idea that __getHours() and __setHours()
> were methods of a class just because of an accessor definition, which is
> why I worked to have Reflection hide that fact.  If I were to go about this
> again, they probably will not be methods of the class.  Internally there is
> little requiring an op_array to be attached to a class in order to be
> executed.****
>
>
> > 2. isset is defined as:
> >         isset() { return $this->Hours != NULL; } This does not seem to
> be correct - != NULL does not work like isset now.
> > Try this:
> > class A { public $x = 0; }
> > $a = new A;
> > var_dump(isset($a->x));
> > var_dump($a->x != NULL);
> > This needs to be fixed - generated isset() should be defined to work
> exactly like regular isset and actually use the same code path.
> > Argument to isset() call can be retrieved using accessor but it should
> not differ from isset() result in any possible way or situation
> > (including error situations - e.g. notices, etc.)****
>
> The reason that = NULL and != NULL was chosen is because isset() and
> unset() are special states that are available only to a variable or
> property, since a get/set do not return a real property they cannot be used
> with isset/unset.  Now that there has been discussion of an accessor being
> a real property shadowed by get/set, standard isset/unset could potentially
> be used against the underlying property.****
>
>
> > 3. How references and complex cases are handled? Didn't find anything
> about it, e.g. how it handles $foo->bar++, $foo->bar[] = 1,
> > $foo->bar[123] = 4, etc. ($foo->bar being property with get/set defined
> of course)? How $foobar =& $foo->bar is handled? The sort()
> > case mentions by-ref return but does not explicitly mention all other
> cases.
> > These need to be covered explicitly in the RFC.****
>
> This is covered in the RFC, perhaps not clearly enough (let me know how I
> could expand on it further for clarity).  To answer each of your questions,
> you can think of what would happen as if it were a function call.  For
> example, if you did $foo->bar()[123] = 4 you would be modifying a
> return-by-val.  If bar were instead defined as returning a reference, then
> it would indeed work as you expect above.  $foobar = &$foo->bar would work
> as expected as long as the getter is returning a reference as well.
>
> I, perhaps mistakenly, assumed that if return-by-ref and sort() worked
> properly, then all other "usages of references" should equally work the
> same, is that not right?  If it's not right, why not?****
>
>
> > 4. We have some LSP controls now in place to ensure non-LSP overrides
> generate E_STRICT. Will this be the case for properties too?
> > Meaning, what happens if you add overriding protected getter to a
> property that was previously fully public - thus violating the LSP?****
>
> Certainly, this basic object oriented functionality, of course it is
> upheld.  This is one of the reasons I leveraged standard functions in the
> first place, because these issues were automatically handled by the
> existing core.****
>
>
> >
> > 5. What happens if you override accessor property with plain old
> variable property? I.e.:
> >
> > class A {
> >    protected $secret {
> >       get() { return "secret"; }
> >   }
> > }
> >
> > class B extends A {
> >    public $secret = "not a secret anymore"; }
> >
> > Also, what happens here if A extends B in the same scenario (this refers
> to the #4 too).****
>
> This is currently up in the air on the RFC side and is being referred to
> as which "shadows" which.  The code currently has it that properties shadow
> accessors, Nikita suggested that should be inverted and I agree, so unless
> someone else thinks otherwise, accessors will probably shadow properties.*
> ***
>
>
> >
> > 6. Thinking more about isset/unset - why not make isset/unset always be
> the default unless overridden? I can't really see the case
> > where you want echo $foo->bar to work but if(isset($foo->bar)) echo
> $foo->bar to not work. I think isset() and unset() should always
> > use automatic implementations by default (fixed in accord with #2 of
> course).****
>
> See response to #2 above, without a getter/setter returning a real
> property, isset/unset accessors were necessary because isset()/unset()
> cannot perform on a dynamic value.  Consider this: unset($foo->bar()) or
> isset($foo->bar()).  Since we are moving in the direction of accessors
> shadowing properties, I could see the default implementation of isset/unset
> actually be more like unset() { return unset($this->bar); } and isset() {
> return isset($this->bar); }****
>
>
> > 7. "Error messaging" section is not clear. Some examples would help -
> what is being translated to what?****
>
> I will expand on this section in the RFC, but this section is referring to
> the fact that if bar were an accessor without a set() and this were
> attempted:
>
> $foo->bar = 4;
>
> It would have errored with:
>         Fatal error: no function __setbar() exists on object $foo
> <-- That is not exactly the message returned by core, but you get the point
>
> So the section on error messaging is referring to the fact that all errors
> involving accessors have been changed to make more sense, ie:
>         Fatal error: cannot set $foo->bar, no setter is defined.****
>
>
> > 8. "Static accessors" section is not clear, namely this one:
> > This yielded the possibility that a getter call was being made while it
> should not be allowed (if there was no getter defined) and so
> > pass_two() was changed to look for these non-backpatched illegal static
> getter calls and a compile time error is produced.
> >
> > When the code is compiled, the class definition (and, in fact, the name
> of the class we're talking about) may not be available, so how
> > can you known if certain property of this class has getters defined?****
>
> Oh crap, you're referring to the idea that during compilation a class
> definition may exist below the point of "current compilation," right?  I
> had not considered this case and you're right, this would break badly.****
>
>
> > Also, I'm not sure what is the thing about backpatching and converting
> to function calls - I think it should work via engine handlers
> > just as the rest of the things work in the engine, is it not the case?
> If not, it should be made the case.****
>
> The static accessors was above my pay grade when I first tackled them, in
> comparison the object get/set was a piece of cake because it was already
> being handled by __get() and __set() but static properties are handled in
> an entirely different way.  Because of the nearly completely undocumented
> code, I could not make heads nor tails of how it worked.  I still do not
> know if I could make this work at the vm/opcode level during runtime but
> I'd be much more willing to give it a go now.
>
> Most of my deep questions over the last year have gone unanswered and so I
> was left to my own devices to find a way to make it work.****
>
>
> > 9. This:
> > Eliminate the ability for an accessor to be called via $o→__getHours(),
> the accessor functions will be completely unavailable for use
> > except as property references ($o→Hours)
> >
> > I think it a mistake. More magic and complication in the engine is not a
> good thing and would require tons of special case checks in
> > all places where we deal with functions. I think it is wrong - if we
> create a callable entity, it should be callable. __ in the name is the
> > indication enough that you're dealing with special method and you should
> tread carefully, we should not go out of our way to mess
> > up the engine to prevent it.****
>
> You and Nikita get your gloves on, makes it easier on me to go your
> direction but Nikita did not like this at all.****
>
>
> > 10. I'm not sure what the point about debug_backtrace() is but again, we
> should not create more complicated magic there, it just
> > should show what really is happening.****
>
> This would refer to the fact that a debug backtrace would show that it's
> in a function called __getHours() (for example) which would only serve to
> confuse a php developer who doesn't know that a getter for $Hours is really
> a function named __getHours().  Therefore I will be patching the error so
> that it indicates something the php developer will understand, namely that
> the line is referring to a getter.****
>
>
> > 11. About read-only/write-only thing - I like not having the keywords,
> but it is still not clear how final produces read-only property -
> > do I say something like "final set();" or how can I say "there's no set
> and never will be"?****
>
> I could not get this point across to anyone but gave up, private final
> set(); != read-only.  With a non "read-only" keyword scenario, a "set" call
> would still be allowed and would show up as an access violation to outside
> observers and would be allowed from within the class.  This is not what I
> wanted but I had enough other points of contention and I yielded on this.*
> ***
>
>
> > I'm sorry if some points were already discussed - I scanned through the
> multiple threads but may very well missed something in
> > 100+ messages that there are, in any case I feel most of the questions
> above must be reflected in RFC explicitly.
> >
> > Thanks,
> > --
> > Stanislav Malyshev, Software Architect
> > SugarCRM: http://www.sugarcrm.com/
> > (408)454-6900 ext. 227****
>
> ** **
>

Reply via email to