Dear Herve Thank you for your helpful comments, and I especially appreciate that you tried to run my package. I will try to answer each point separately.
Herve Pages wrote:
Hi Christian, I can only give you a few reasons why IMO it is very unlikely that anybody will be able to help you on this, with the current form of your post. 1) Unless you have a really good reason to do so, don't attach a package to your post. Do your best to provide a few lines of code that anybody can easily copy and paste into their session.
Sorrowly, sometimes, a few lines of code are not sufficient to show the problem. Furthermore, most of the time there are complaints that people do not provide enough information, an issue I wanted to avoid. At the end of my answer I provide now the minimal necessary code for people to easily copy-paste into their session. Nevertheless, I also attach the same code as package, since some problems only appear when compiling the package, concretely: The behavior of the attached package is completely different, when I "exportMethods("initialize")" in the NAMESPACE file or not. To see the changes, please comment-out this one line in the NAMESPACE file.
2) Your package is messy (yes I looked at it). You have far too many classes with far too many slots that we don't care about. If you could provide the smallest possible set of classes with the smallest possible set of slots with the smallest possible set of generics and methods that still allow to reproduce the issue you want to show us, that would help!
You are correct, I wanted to provide a complete demo-package. As mentioned above, I provide now the minimal necessary code (at least I hope so).
3) You show us an example where BaseClass is VIRTUAL (which is indeed how it is defined in your package) and then an example where BaseClass is NOT VIRTUAL. How can we reproduce the latter? Don't expect people to go into your package, change the class definition, reinstall, restart R and then run your example!
I thought, it would be easy for developers to understand what I mean and to simply comment-out the one line in the definition of BaseClass.
4) Note that for clarity and conformance to almost universal convention, it's better to use arrows pointing from derived classes to base classes in your inheritance tree.
Sorry, my mistake.
5) It's good to provide the inheritance tree, but it's better when it's complete. I've looked at what you actually have in your package and the complete inheritance tree is something like this: BaseClass <- SubClassA <- SubClassB <- SubSubClassA <- SubSubClassB Where is the SubClassA class in the inheritance tree that you included in your post below?
Sorry, my mistake.
6) Another thing I note is that you have a naming problem: any reason why you name "SubSubClassA" a subclass of SubClassB? Given that you also have defined SubClassA, this can only lead to confusion!
Again, you are correct, my mistake. Here is the corrected inheritance tree: BaseClass <- SubClassA <- SubClassB <- SubSubClassB1 <- SubClassB <- SubSubClassB2
7) You need to use proper terminology if you expect people to follow you. In your post below, every time you instanciate a class you say that your are creating it: o "First, I need to create SubClassA..." o "I create both subclasses, SubSubClassA and SubSubClassB..." o etc... Creating a class is not the same as instanciating it!
You are correct, this was confusing. I meant, theat I create an object, which is probably the same as instanciating a class? Here is the actual code to use:> subA <- new("SubClassA",filename="OutSubA",filedir="/Volumes/CoreData/CRAN/",namesubA="NameSubA") > subsubB1 <- new("SubSubClassB1",filename="MyFileNameB1",filedir="/Volumes/CoreData/",subA=subA) > subsubB2 <- new("SubSubClassB2",filename="MyFileNameB2",filedir="/Volumes/CoreExtra",subA=subA)
8) You start your examples by "First, I need to create SubClassA..." so you are introducing us a class that doesn't show up in your inheritance tree so we don't know how it is related to the other classes. Also you say that you "need" to create SubClassA but we have no idea why!
Once again you are correct, this was confusing. I need to create object "subA" of class SubClassA, since it is a slot of SubClassB, and needs to be included in the instanciation of objects "subsubB1" and "subsubB2".
9) You have a slot in SubClassB that is of class SubClassA! This means "a SubClassB object _is_ a BaseClass object and it _has_ a slot that is itself a BaseClass object (since a SubClassA object is a BaseClass object too)". I hope that this is really what you want... but maybe this could be related to the fact that you see 2 instanciations of BaseClass when you instanciate SubSubClassA or SubSubClassB.
This is the most IMPORTANT point and may be the cause of my problems: YES, both SubClassA and SubClassB are derived from BaseClass, AND SubClassA is a slot of SubClassB. This is what I want indeed! In real OOP languages such as C++ and Java this is no problem, and I really hope that this is possible when using S4 classes, too.
10) You have several different issues (initialize called multiple times when you expect only 1 time, setValidity not called, etc..). May be they are related, maybe they are not. If you can isolate those problems and make a separate post for each of them, that would help too.
Once again, you are correct, and normally I post these poblems seperately. However, since I discovered all these problems while trying to solve the main problem with my classes myself, I have mentioned them in my post.
You'll be surprised, but once you've made the effort to follow those recommendations, it's most likely that you will have a better understanding of what's going on. And you might even be able to sort out these issues by yourself!
As you see, I tried to follow most (all?) of your recommendations, but sorrowly, the problem remains the same. When you copy-paste the code below and then do:subA <- new("SubClassA",filename="OutSubA",filedir="/Volumes/CoreData/CRAN/",namesubA="NameSubA") subsubB1 <- new("SubSubClassB1",filename="MyFileNameB1",filedir="/Volumes/CoreData/",subA=subA) subsubB2 <- new("SubSubClassB2",filename="MyFileNameB2",filedir="/Volumes/CoreExtra",subA=subA)
you will see that "subA" and "subsubB1" give the correct result, but "subsubB2" results in the error that "filename" is missing, although it is supplied.
Cheers, H.
Thus, I would really appreciate any help. Best regards Christian# - - - - - - - - - - - - - - - - - - BEGIN - - - - - - - - - - - - - - - - - - - - -
setClass("BaseClass", representation(filename = "character", filedir = "character", "VIRTUAL" # filedir = "character" ), prototype(filename = character(), filedir = as.character(getwd()) ) )#BaseClass setClass("SubClassA", representation(namesubA = "character"), contains=c("BaseClass"), prototype(namesubA = "") )#SubClassA setClass("SubClassB", representation(subA = "SubClassA", data = "data.frame" ), contains=c("BaseClass"), prototype(subA = new("SubClassA"), data = data.frame(matrix(nr=0,nc=0)) ) )#SubClassB setClass("SubSubClassB1", contains=c("SubClassB") )#SubSubClassB1 setClass("SubSubClassB2", representation(namesubsubB2 = "character"), contains=c("SubClassB"), prototype(namesubsubB2 = "MySubSubB2") )#SubSubClassB2# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
validMsg <- function(msg, result) { if (is.character(result)) { append(msg, result); } else { msg; }#if }#validMsg pathFile <- function(filename=character(0), filedir=character(0)) { print("------pathFile------") if (length(filename) != 0) { filename <- basename(filename); }#if if (length(filename) == 0) { filename <- as.character("ERROR_MISSING_FILENAME"); }#if if (dirname(filename) != ".") { filedir <- dirname(filename); }#if if (filedir == "" || filedir == ".") { filedir <- as.character(getwd()); }#if if (substr(filedir, nchar(filedir), nchar(filedir)) == "/") { filedir <- substr(filedir, 0, nchar(filedir)-1); }#if dirfile <- paste(filedir, "/", filename, sep=""); return(dirfile); }#pathFile# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"initialize.BaseClass" <-function(.Object, filename=character(), filedir=as.character(getwd()), ...) {
print("------initialize:BaseClass------") print(paste("BaseClass:init:class(.Object) = ", class(.Object))) # .Object <- callNextMethod(.Object, ...); dirfile <- pathFile(filename, filedir); print(paste("BaseClass:init:dirfile = ", dirfile)).Object <- callNextMethod(.Object, filename=filename, filedir=filedir, ...);
[EMAIL PROTECTED] <- filename; [EMAIL PROTECTED] <- filedir; .Object; }#initialize.BaseClass setMethod("initialize", "BaseClass", initialize.BaseClass); setValidity("BaseClass", function(object) { print("------setValidity:BaseClass------") print(paste("BaseClass:val:class(object) = ", class(object))) msg <- NULL; if (!(is.character([EMAIL PROTECTED]))) { # if (is.na(file.dir([EMAIL PROTECTED]))) { msg <- validMsg(msg,paste(sQuote("filedir"), "is not a system directory"));
}#if print(paste("BaseClass:val:filedir = ",[EMAIL PROTECTED])) if (is.null(msg)) TRUE else msg; } )#setValidity# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"initialize.SubClassA" <- function(.Object, namesubA="MyNameSubA", ...) { print("------initialize:SubClassA------") print(paste("SubClassA:init:class(.Object) = ", class(.Object))) # .Object <- callNextMethod(.Object, ...); if (namesubA == "") { namesubA <- "DefaultNameSubA"; }#if print(paste("SubClassA:init:namesubA = ", namesubA)) .Object <- callNextMethod(.Object, namesubA=namesubA, ...); [EMAIL PROTECTED] <- namesubA; #validObject(.Object); .Object; }#initialize.SubClassA setMethod("initialize", "SubClassA", initialize.SubClassA); setValidity("SubClassA", function(object) { print("------setValidity:SubClassA------") print(paste("SubClassA:val:class(object) = ", class(object))) msg <- NULL; strg <- [EMAIL PROTECTED]; if (!(is.character(strg) && nchar(strg) > 0)) { msg <- validMsg(msg, paste(sQuote("namesubA"), "is missing")); }#if print(paste("SubClassA:val:namesubA = ",[EMAIL PROTECTED])) if (is.null(msg)) TRUE else msg; } )#setValidity# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"initialize.SubClassB" <- function(.Object, subA=new("SubClassA"), data = data.frame(), ...) { print("------initialize:SubClassB------") print(paste("SubClassB:init:class(.Object) = ", class(.Object))) # .Object <- callNextMethod(.Object, ...); .Object <- callNextMethod(.Object, subA=subA, data=data, ...); [EMAIL PROTECTED] = subA; [EMAIL PROTECTED] = data; .Object; }#initialize.SubClassB setMethod("initialize", "SubClassB", initialize.SubClassB); setValidity("SubClassB", function(object) { print("------setValidity:SubClassB------") print(paste("SubClassB:val:class(object) = ", class(object))) msg <- NULL; ## check filename strg <- [EMAIL PROTECTED]; # if (!(is(strg, "character") && nchar(strg) > 0)) { if (!(is.character(strg) && length(strg) > 0)) { msg <- validMsg(msg, paste(sQuote("filename"), "is missing")); }#if print(paste("SubClassB:val:filename = ",[EMAIL PROTECTED])) if (is.null(msg)) TRUE else msg; } )#setValidity# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"initialize.SubSubClassB1" <- function(.Object, ...) { print("------initialize:SubSubClassB1------") print(paste("SubSubClassB1:init:class(.Object) = ", class(.Object))) .Object <- callNextMethod(.Object, ...); #validObject(.Object); .Object; }#initialize.SubSubClassB1 setMethod("initialize", "SubSubClassB1", initialize.SubSubClassB1); setValidity("SubSubClassB1", function(object) { print("------setValidity:SubSubClassB1------") print(paste("SubSubClassB1:val:class(.Object) = ", class(object))) msg <- NULL; if (is.null(msg)) TRUE else msg; } )#setValidity# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"initialize.SubSubClassB2" <- function(.Object, namesubsubB2="MyNamesubsubB2", ...) { print("------initialize:SubSubClassB2------") print(paste("SubSubClassB2:init:class(.Object) = ", class(.Object))) # .Object <- callNextMethod(.Object, ...); ## set default subsubnameB if (namesubsubB2 == "") { namesubsubB2 <- "DefaultNamesubsubB"; }#if print(paste("SubSubClassB2:init:namesubsubB2 = ", namesubsubB2)) .Object <- callNextMethod(.Object, namesubsubB2=namesubsubB2, ...); [EMAIL PROTECTED] <- namesubsubB2; #validObject(.Object); .Object; }#initialize.SubSubClassB2 setMethod("initialize", "SubSubClassB2", initialize.SubSubClassB2); setValidity("SubSubClassB2", function(object) { print("------setValidity:SubSubClassB2------") print(paste("SubSubClassB2:val:class(object) = ", class(object))) msg <- NULL; ## check subsubnameB strg <- [EMAIL PROTECTED]; if (!(is.character(strg) && nchar(strg) > 0)) { msg <- validMsg(msg, paste(sQuote("namesubsubB2"), "is missing")); }#if print(paste("SubSubClassB2:val:namesubsubB2 = ",[EMAIL PROTECTED])) if (is.null(msg)) TRUE else msg; } )#setValidity# - - - - - - - - - - - - - - - - END - - - - - - - - - - - - - - - - - - - - - - -
myclasspkg2_0.1.1.tar.gz
Description: GNU Zip compressed data
______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel