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