[Rd] Problem using callNextMethod() in S4

cstrato cstrato at aon.at
Sun Mar 4 19:51:45 CET 2007


Dear Seth

Thank you for your comments. Please see my comments and at the end my 
corrected code and output.
Sorrowly, the problem remains the same.

Seth Falcon wrote:
> cstrato <cstrato at aon.at> writes:
>
>   
>> Dear all,
>>
>> Maybe, I am doing something wrong, but using R-2.5.0 on my Intel-Mac, I 
>> have problems
>> using function callNextMethod() in method initialize.
>>
>> I am loading the following code as file "testS4.R":
>>     
>
> I don't think this is the code in the same state as that which you ran
> the examples.  Did you add/remove some comment lines perhaps?
>
> After copy/pasting the code you posted, I get:
>
>     > tmp<-new("derivedClass")
>     [1] "---initialize:derivedClass---"
>     [1] "mytitle =  MyTitle"
>     > tmp<-new("derivedClass",myname="testname",mytitle="testitle")
>     [1] "---initialize:derivedClass---"
>     [1] "mytitle =  MyTitle"
>
>   
I am sorry, you are correct, I have commented out ".Object <- 
callNextMethod()" in method
initialize for derivedClass afterwards.
>> setValidity("baseClass",
>>    function(object) {
>> print("---setValidity:baseClass---")
>>       strg <- object at myname;
>>       if (!(is(strg, "character") && nchar(strg) > 0)) {
>>          warning(paste(sQuote("myname"), "is missing"));
>>       }#if
>> print(paste("myname = ",object at myname))
>>       strg <- object at mydir;
>>       if (!(is(strg, "character") && file.exists(strg))) {
>>          warning(paste(sQuote("mydir"), "is not a system directory"));
>>       }#if
>>       if (substr(strg, nchar(strg), nchar(strg)) == "/") {
>>          object at mydir <- substr(strg, 0, nchar(strg)-1);
>>       }#if
>> print(paste("mydir = ",object at mydir))
>>    }
>> )#setValidity
>>     
>
> Your validity function isn't valid :-P It should either return TRUE or
> return a character vector describing what isn't valid about the
> object.  Don't call warning() or print().
>   
Please see my corrected code where I use "validMsg()" from BioBase.
> Also, you don't need those ';'
>
> And finally, you are operating on a _copy_ in the validity method
> (just like everywhere else) and so this
>
>   
>>       if (substr(strg, nchar(strg), nchar(strg)) == "/") {
>>          object at mydir <- substr(strg, 0, nchar(strg)-1);
>>       }#if
>>     
>
> will not have any effect on the instance passed in.  It is an odd
> thing to do in a validity method.
>   
You are right, I moved this code to method "initialize".
> + seth
>
>   
Here is my new code "testS4.R" (as used in the output):

setClass("baseClass",
   representation(myname = "character",
                  mydir  = "character",
                  "VIRTUAL"),
   prototype(myname = "",
             mydir  = "")
)#baseClass

setClass("derivedClass",
   representation(mytitle = "character"),
   contains=c("baseClass"),
   prototype(mytitle = "")
)#derivedClass

# taken from package BioBase: tools.R
validMsg <- function(msg, result) {
   if (is.character(result)) {
      append(msg, result);
   } else {
      msg;
   }#if
}

setMethod("initialize", "baseClass",
   function(.Object, ...) {
print("---initialize:baseClass---")
#    .Object <- callNextMethod();
      strg <- .Object at mydir;
print(paste("base:strg = ", strg))
      if (strg == "") {
         .Object at mydir <- as.character(getwd());
      }#if
      if (substr(strg, nchar(strg), nchar(strg)) == "/") {
         .Object at mydir <- substr(strg, 0, nchar(strg)-1);
      }#if
print(paste("base:mydir = ", .Object at mydir))
    .Object <- callNextMethod();
    .Object;
   }
)#initialize

setValidity("baseClass",
   function(object) {
print("---setValidity:baseClass---")
      msg <- NULL;
      strg <- object at myname;
      if (!(is(strg, "character") && nchar(strg) > 0)) {
         msg <- validMsg(msg, paste(sQuote("myname"), "is missing"));
      }#if
print(paste("base:myname = ",object at myname))
      strg <- object at mydir;
      if (!(is(strg, "character") && file.exists(strg))) {
         msg <- validMsg(msg, paste(sQuote("mydir"), "is not a system 
directory"));
      }#if
print(paste("base:mydir = ",object at mydir))
      if (is.null(msg)) TRUE else msg;
   }
)#setValidity

setMethod("initialize", "derivedClass",
   function(.Object, ...) {
print("---initialize:derivedClass---")
#    .Object <- callNextMethod();
      if (.Object at mytitle == "") {
         .Object at mytitle = "MyTitle";
      }#if
print(paste("derived:mytitle = ",.Object at mytitle))
    .Object <- callNextMethod();
    .Object;
   }
)#initialize

setValidity("derivedClass",
   function(object) {
print("---setValidity:derivedClass---")
      msg <- NULL;
      strg <- object at mytitle;
      if (!(is(strg, "character") && nchar(strg) > 0)) {
         msg <- validMsg(msg, paste(sQuote("mytitle"), "is missing"));
      }#if
print(paste("derived:mytitle = ",object at mytitle))
      if (is.null(msg)) TRUE else msg;
   }
)#setValidity


Here is the new output with the same error:

 > library(methods)
 > source("testS4.R")
 > tmp<-new("derivedClass")
[1] "---initialize:derivedClass---"
[1] "derived:mytitle =  MyTitle"
[1] "---initialize:baseClass---"
[1] "base:strg =  "
[1] "base:mydir =  /Volumes/CoreData/CRAN/Workspaces/tests"
 >
 > tmp<-new("derivedClass",myname="testname",mydir="",mytitle="testitle")
[1] "---initialize:derivedClass---"
[1] "derived:mytitle =  MyTitle"
[1] "---initialize:baseClass---"
[1] "base:strg =  "
[1] "base:mydir =  /Volumes/CoreData/CRAN/Workspaces/tests"
[1] "---setValidity:baseClass---"
[1] "base:myname =  testname"
[1] "base:mydir =  "
Error in validObject(.Object) : invalid class "derivedClass" object: 
'mydir' is not a system directory

I do not understand why "mydir" is not recognized correctly?

Thank you
Christian



More information about the R-devel mailing list