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 - - - - - - - - - - - - - - - - - - - - - - -

Attachment: 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

Reply via email to