Hello,
The XOTcl manual says that an abstract method produces an error if it is called directly. It seems that this is not always the case. E.g., in the following example there is no error:
Class C C abstract instproc a {} C instproc b {} {my a}
C test test b
From an earlier discussion on the mailing list I found that predefined.xotcl contains the following code to avoid errors when an abstract method is invoked by "next":
Object instproc abstract {methtype methname arglist} { if {$methtype != "proc" && $methtype != "instproc"} { error "invalid method type '$methtype', \ must be either 'proc' or 'instproc'." } [self] $methtype $methname $arglist " if {[self callingproc] != [self proc] && [self callingobject] != [self]} { error "Abstract method $methname $arglist called" } " }
I guess the test should be "||" instead of "&&" ? But then, it doesn't do the right thing either, because callingproc is empty in case of an invocation by "next".
Regards, Koen Danckaert
Hi Koen,
it seems you've found a bug. The Method in predefined.xotcl should probably look like this:
::xotcl::Object instproc abstract {methtype methname arglist} { if {$methtype != "proc" && $methtype != "instproc"} { error "invalid method type '$methtype', \ must be either 'proc' or 'instproc'." } ::xotcl::my $methtype $methname $arglist " if {[::xotcl::self callingproc] == [::xotcl::self proc] && [::xotcl::self callingobject] == [::xotcl::self]} { ::xotcl::next } else { error "Abstract method $methname $arglist called" } " }
you can simply put this correction (which should also go into the next release) into the file and re-compile, or if you do not want to recompile, overwrite the abstract method before running your program.
Uwe
Koen Danckaert wrote:
Hello,
The XOTcl manual says that an abstract method produces an error if it is called directly. It seems that this is not always the case. E.g., in the following example there is no error:
Class C C abstract instproc a {} C instproc b {} {my a}
C test test b
From an earlier discussion on the mailing list I found that predefined.xotcl contains the following code to avoid errors when an abstract method is invoked by "next":
Object instproc abstract {methtype methname arglist} { if {$methtype != "proc" && $methtype != "instproc"} { error "invalid method type '$methtype', \ must be either 'proc' or 'instproc'." } [self] $methtype $methname $arglist " if {[self callingproc] != [self proc] && [self callingobject] != [self]} { error "Abstract method $methname $arglist called" } " }
I guess the test should be "||" instead of "&&" ? But then, it doesn't do the right thing either, because callingproc is empty in case of an invocation by "next".
Regards, Koen Danckaert _______________________________________________ Xotcl mailing list Xotcl@alice.wu-wien.ac.at http://alice.wu-wien.ac.at/mailman/listinfo/xotcl
Hi Uwe,
This solution indeed produces an error for the case I mentioned before, but now it also gives errors when an abstract method is invoked by "next". I think that callingproc and callingobject cannot be used to test whether a method has been invoked by next. They are not modified through a next call, as shown by the following code:
Class C C instproc a {} { puts "callingproc : '[self callingproc]'" puts "callingobject : '[self callingobject]'" }
Class D -superclass C D instproc a {} {next} D instproc b {} {my a}
D test test a test b
This produces: callingproc: '' callingobject: '' callingproc: 'b' callingobject: '::test'
So it is as if there was no intermediate "next" call.
Koen
Uwe Zdun wrote:
it seems you've found a bug. The Method in predefined.xotcl should probably look like this:
::xotcl::Object instproc abstract {methtype methname arglist} { if {$methtype != "proc" && $methtype != "instproc"} { error "invalid method type '$methtype', \ must be either 'proc' or 'instproc'." } ::xotcl::my $methtype $methname $arglist " if {[::xotcl::self callingproc] == [::xotcl::self proc] && [::xotcl::self callingobject] == [::xotcl::self]} { ::xotcl::next } else { error "Abstract method $methname $arglist called" } " }