Hi!

> 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

I think PHP engine has enough complexity and we do not need to add more
unwarranted one. These are methods, they exist - so they should exist
everywhere methods exist. Doing otherwise will result in a tons of
inconsistencies and weird occurrences. If you are in __getHours method
but the engine says __getHours does not exist and can not be called, it
is bad magic. There's no use case for this bad magic and I see no reason
for it except for us trying to restrict users for purist reasons. I do
not think the engine needs complex bad magic when simple solution of
making regular methods would work just as well in all cases where
methods work.

> 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.

So methods of what would they be? What would be their scope? What would
$this mean? What would method name and backtrace report? How
debugging/profiling tools would work with them? I see no need to
reinvent complex APIs that would require dozens of changes in all tools
dealing with PHP engine when simple methods approach would work as well.
If they won't be regular methods I think it would be too much trouble to
have yet another entity which is "like method but not really a method"
in the engine.

> 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

I'm not sure I understand here. Property can be either set (exists and
not storing null) or not, there's nothing special about it - all
variables and properties work this way. Automatic isset should work
*exactly* like plain PHP's isset(), and unset should make variable into
the state where isset returns false (and resources are freed). The code
in the RFC for isset() is not working like PHP's isset. That should be
fixed.

> 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

Yes, it needs to be expanded, since no examples right now show how it is
supposed to be working.

> 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?

I'm not sure, I didn't check all of them yet. All these need to be tested.

> 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.

I'm not sure overriding "public $foo" with "public $foo { protected
get() {} }" is covered by existing code. Existing code has no way to
cover such things.

> 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.

Which raises the question above again - how LSP is preserved? What would
happen in such case?

> 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:

You seem to misunderstand what I wrote there. I am proposing that
isset() would a) always have default implementation if get() is defined
and b) work exactly like PHP isset() in that the way that if get()
returns null (or does not exist if write-only properties are introduced)
then it returns false, otherwise it returns true.
The fact that current isset() operator does not work on T variables is
irrelevant, since I'm talking about level below that - how that operator
is implemented. The implementation should be augmented so that for
properties with accessors it would work exactly the same as for
properties without ones.

> 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); }

If this is pseudocode, meaning "call get accessor if exists and return
true if return value is not null, otherwise return false" then it's fine
for isset. For unset, you'd still want to use set accessor or fail if
set accessor is not 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.

Yes, class definition is runtime, when you compiling code you have no
idea not only what this class is, but thanks to $foo::bar also what this
class' name is (which is no different since if you had the name you
still had no idea what class is under this name).

> 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.

I think you'd need some additional hooks in the class structure for this
and some additional methods in zend_object_handlers.c. If you need more
on this please send me a message, I'll try to help you (though next 2
weeks I'll have very sketchy internet access as I'm on
vacation/traveling, so please be patient :)

> You and Nikita get your gloves on, makes it easier on me to go your
> direction but Nikita did not like this at all.

Well, I think I've explained my approach above, if Nikita has something
to add he's most welcome.

> 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

I think it's a wrong approach to lie to the developer in order to make
it "easier". If the engine has function __getHours, it should say so.
The developer smart enough to use properties is smart enough to
understand very simple concept of auto-generated function name (given
that __get exists for years in the engine).

> 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 see. I guess this should be TODO then, maybe somebody will have better
ideas. I really don't like special case keywords, so it'd be great if we
could figure it out using generic approach or maybe some light magic
like autogenerated method throwing predefined exception.
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to