Thread: [cedet-eieio] [eieio] :before and :after methods not called
Brought to you by:
zappo
From: drkm <dar...@ya...> - 2005-03-07 13:28:03
|
Hi It seems that the generic dispatcher doesn't call all :before and :after methods as it would have to. For example, this: (defclass A () ()) (defclass AA (A) ()) (defclass AAA (AA) ()) (defmethod F ((p A)) (message "F A")) (defmethod F ((p AA)) (message "F AA")) (defmethod F :BEFORE ((p A)) (message "F A before")) (defmethod F :BEFORE ((p AA)) (message "F AA before")) (defmethod F :BEFORE ((p AAA)) (message "F AAA before")) (defmethod F :AFTER ((p A)) (message "F A after")) (defmethod F :AFTER ((p AA)) (message "F AA after")) (defmethod F :AFTER ((p AAA)) (message "F AAA after")) (F (AAA nil)) prints: F AAA before F AA F AAA after instead of: F AAA before F AA before F A before F AA F A after F AA after F AAA after --drkm |
From: drkm <dar...@ya...> - 2005-03-11 17:55:27
|
drkm writes: > It seems that the generic dispatcher doesn't call all :before > and :after methods as it would have to. As quoted in my previous posting, the CLOS specs says: - All the :before methods are called, in most-specific-first order. Their values are ignored. An error is signaled if call-next-method is used in a :before method. - [...] - All the :after methods are called, in most-specific-last order. Their values are ignored. An error is signaled if call-next-method is used in a :after method. So all these methods have to be called. And call-next-method can't be used in these (as in eieio-tests.el :-o). Sorry, I don't have the time to write some test case for it. But it could be simple, by using something similar to the patch to test the value of a generic function call I just posted. By pushing a symbol in each method, and checking the resulting list is the required one. Thanks, --drkm |
From: Eric M. L. <er...@si...> - 2005-03-17 02:07:44
|
Howdy all, I have indeed finally found the reference to how these methods should be called in my favorite CLOS hyperspec. I was oblivious to the specific paragraph before. http://www.lispworks.com/documentation/HyperSpec/Body/07_ffb.htm It's sort-of in the middle-ish of that page with three sub-bullets. Anyway, there are some pretty subtle changes in EIEIO required to manage this, plus changes to code depending on various dependant behaviors for this, and some of the other email invovled. As a side effect, if I can get things working correctly, I will probably post yet ANOTHER beta of cedet to allow some recovery on dependent packages as the effects of the new error messages have been somewhat devastating in my own code. As I get some of this stuff checked in, I'll post about the changes and how to solve problems that may be caused, though that may not be today. :( Thanks for the detailed look-up of the actual rules. Eric >>> drkm <dar...@ya...> seems to think that: > Hi > > It seems that the generic dispatcher doesn't call all :before >and :after methods as it would have to. For example, this: > > (defclass A () ()) > (defclass AA (A) ()) > (defclass AAA (AA) ()) > > (defmethod F ((p A)) > (message "F A")) > (defmethod F ((p AA)) > (message "F AA")) > > (defmethod F :BEFORE ((p A)) > (message "F A before")) > (defmethod F :BEFORE ((p AA)) > (message "F AA before")) > (defmethod F :BEFORE ((p AAA)) > (message "F AAA before")) > > (defmethod F :AFTER ((p A)) > (message "F A after")) > (defmethod F :AFTER ((p AA)) > (message "F AA after")) > (defmethod F :AFTER ((p AAA)) > (message "F AAA after")) > > (F (AAA nil)) > >prints: > > F AAA before > F AA > F AAA after > >instead of: > > F AAA before > F AA before > F A before > F AA > F A after > F AA after > F AAA after > >--drkm > > > >------------------------------------------------------- >SF email is sponsored by - The IT Product Guide >Read honest & candid reviews on hundreds of IT Products from real users. >Discover which products truly live up to the hype. Start reading now. >http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click >_______________________________________________ >Cedet-devel mailing list >Ced...@li... >https://lists.sourceforge.net/lists/listinfo/cedet-devel > -- Eric Ludlam: za...@gn..., er...@si... Home: http://www.ludlam.net Siege: www.siege-engine.com Emacs: http://cedet.sourceforge.net GNU: www.gnu.org |
From: drkm <dar...@ya...> - 2005-03-17 11:43:14
|
"Eric M. Ludlam" <er...@si...> writes: > Anyway, there are some pretty subtle changes in EIEIO required to > manage this, plus changes to code depending on various dependant > behaviors for this, and some of the other email invovled. > As a side effect, if I can get things working correctly, I will > probably post yet ANOTHER beta of cedet to allow some recovery on > dependent packages as the effects of the new error messages have > been somewhat devastating in my own code. Yes. I hope not too much code depends on these behavior. But if some compatibility with CLOS is desired (it could be not, as a design choice), I think these changes are to be make the most rapidly. And if some compatibility with CLOS is desired, the standard method combination *must* be implemented, as a minimum requirement, IMHO. Thanks for your work. It's really fun to developp in Emacs with a CLOS-like implementation :-) --drkm |
From: Eric M. L. <er...@si...> - 2005-04-03 16:18:12
|
Hi, I checked in changes to eieio to do this mechanism for method calls. I submitted a new test file for methodinvocation tests. While I was there, I wrote tests for multiple-inheritance of the same sort. It seemed call-next-method did not call all subclass's method which confused me some. I couldn't find anything in the common list hyperspec on it during a short futile search. If you know what it should do in that case, I'd like to know. Thanks Eric >>> drkm <dar...@ya...> seems to think that: > Hi > > It seems that the generic dispatcher doesn't call all :before >and :after methods as it would have to. For example, this: > > (defclass A () ()) > (defclass AA (A) ()) > (defclass AAA (AA) ()) > > (defmethod F ((p A)) > (message "F A")) > (defmethod F ((p AA)) > (message "F AA")) > > (defmethod F :BEFORE ((p A)) > (message "F A before")) > (defmethod F :BEFORE ((p AA)) > (message "F AA before")) > (defmethod F :BEFORE ((p AAA)) > (message "F AAA before")) > > (defmethod F :AFTER ((p A)) > (message "F A after")) > (defmethod F :AFTER ((p AA)) > (message "F AA after")) > (defmethod F :AFTER ((p AAA)) > (message "F AAA after")) > > (F (AAA nil)) > >prints: > > F AAA before > F AA > F AAA after > >instead of: > > F AAA before > F AA before > F A before > F AA > F A after > F AA after > F AAA after > >--drkm > > > >------------------------------------------------------- >SF email is sponsored by - The IT Product Guide >Read honest & candid reviews on hundreds of IT Products from real users. >Discover which products truly live up to the hype. Start reading now. >http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click >_______________________________________________ >Cedet-devel mailing list >Ced...@li... >https://lists.sourceforge.net/lists/listinfo/cedet-devel > -- Eric Ludlam: za...@gn..., er...@si... Home: http://www.ludlam.net Siege: www.siege-engine.com Emacs: http://cedet.sourceforge.net GNU: www.gnu.org |
From: drkm <dar...@ya...> - 2005-04-04 08:12:24
|
"Eric M. Ludlam" <er...@si...> writes: > I checked in changes to eieio to do this mechanism for method calls. > I submitted a new test file for methodinvocation tests. Good news. > While I was there, I wrote tests for multiple-inheritance of the > same sort. It seemed call-next-method did not call all subclass's ^^^^^^^^ > method which confused me some. I couldn't find anything in the common > list hyperspec on it during a short futile search. If you know what > it should do in that case, I'd like to know. [ I guess you mean "superclass". ] I think you can take a look at "7.6.6.1 Determining the Effective Method" and "7.6.6.2 Standard Method Combination". Basically, the idea is to build a *sorted* list of applicable methods. call-next-method simply call the next method in this list. By example, in the following: (defclass A () ()) (defclass B () ()) (defclass C (A B) ()) (defmethod f ((A a)) ;; 1 (message "A") (when (next-method-p) (call-next-method))) (defmethod f ((B b)) ;; 2 (message "B") (when (next-method-p) (call-next-method))) (defmethod f ((C c)) ;; 3 (message "C") (when (next-method-p) (call-next-method))) The list is (3 1 2) -- I think there is a specific notation I don't remember, so I use numbers. It's not (3 2 1) because A stands on the left, and B on the right, so A takes precedence over B. It begins with 3 because C is the most derived class. Once you've got this list, the standard method combination says to call only the first one. And call-next-method call the next method in this list. [ Note I speak only about standard method combination. I don't know enough what appens in other method combination types, regarding inheritance. ] --drkm |
From: drkm <dar...@ya...> - 2005-04-04 08:43:07
|
drkm <dar...@ya...> writes: > "Eric M. Ludlam" <er...@si...> writes: >> I checked in changes to eieio to do this mechanism for method calls. >> I submitted a new test file for methodinvocation tests. > Good news. I just take a look at this new file. In the second test, you include (F :PRIMARY B-base2) in the result, if I understand. IMHO, it must not be there. The standard method combination take the first applicable primary method, (F :PRIMARY B), because B is the most derived class. This method call call-next-method. So (F :PRIMARY B-base1) is called. B-base1 take precedence over B-base2, because it stands more on the left in the superclass list from the definition of the class B. Because this method doesn't call call-next-method, (F :PRIMARY B-base2) is not called at all. BTW, in the first test, I think it's better to not define (F :PRIMARY AAA). So the result will have to be: (F :BEFORE AAA) (F :BEFORE AA) (F :BEFORE A) (F :PRIMARY AA) (F :AFTER A) (F :AFTER AA) (F :AFTER AAA) I guess starting at different "levels" could be better for testing. Maybe introduce a "hole" in the :BEFORE and :AFTER lists could be of some benefit, too. Like something like that: (F :BEFORE AAA) (F :BEFORE A) (F :PRIMARY AA) (F :AFTER A) (F :AFTER AAA) To be sure the implementation don't just walk in the class inheritence graph until some nil is encountered (or something like that). Thanks, --drkm |
From: Eric M. L. <er...@si...> - 2005-04-14 13:36:42
|
>>> drkm <dar...@ya...> seems to think that: >drkm <dar...@ya...> writes: > >> "Eric M. Ludlam" <er...@si...> writes: > >>> I checked in changes to eieio to do this mechanism for method calls. >>> I submitted a new test file for methodinvocation tests. > >> Good news. > > I just take a look at this new file. In the second test, you >include (F :PRIMARY B-base2) in the result, if I understand. IMHO, it >must not be there. I restored the original behavior here. [ ... ] > BTW, in the first test, I think it's better to not define >(F :PRIMARY AAA). So the result will have to be: > > (F :BEFORE AAA) > (F :BEFORE AA) > (F :BEFORE A) > (F :PRIMARY AA) > (F :AFTER A) > (F :AFTER AA) > (F :AFTER AAA) I changed the test to this. > I guess starting at different "levels" could be better for testing. >Maybe introduce a "hole" in the :BEFORE and :AFTER lists could be of >some benefit, too. Like something like that: > > (F :BEFORE AAA) > (F :BEFORE A) > (F :PRIMARY AA) > (F :AFTER A) > (F :AFTER AAA) > > To be sure the implementation don't just walk in the class >inheritence graph until some nil is encountered (or something like >that). [ ... ] This was a good suggestion as it revealed a bug. I have a method optimizer which conflicts with the new method-list generator, so I ended up with 2 calls to the A implementation of F :BEFORE. I checked in a fix for this also. Now perhaps I can get to some of your other messages. ;) Eric -- Eric Ludlam: za...@gn..., er...@si... Home: http://www.ludlam.net Siege: www.siege-engine.com Emacs: http://cedet.sourceforge.net GNU: www.gnu.org |
From: drkm <dar...@ya...> - 2005-04-20 09:37:50
|
"Eric M. Ludlam" writes: > Now perhaps I can get to some of your other messages. ;) Thanks for your work, and your respond time, as usual. --drkm |