On Fri, Jul 17, 2009 at 11:41 PM, Jim Nemesh<nem...@broad.mit.edu> wrote: > Hi! I'm trying to learn about object oriented R, as it seems like it > would be very useful. > > I'm going over an example from the documentation, and I'm very confused: > > http://www1.maths.lth.se/help/R/R.oo/ > > [assume you've called library (R.oo)] > > setConstructorS3("SavingsAccount", function(balance=0) { > if (!is.numeric(balance) && length(balance) != 1) > throw("Argument 'balance' must be a single numeric value: ", > mode(balance)); > if (balance < 0) > throw("Trying to create an account with a negative balance."); > > extend(Object(), "SavingsAccount", > .balance = balance > ); > }) > > Why would I get the following result? > > > SavingsAccount(5) > [1] "SavingsAccount: 0x18706032" > > SavingsAccount("fruit") > [1] "SavingsAccount: 0x605387128" > > The second time, the input should fail, balance is not numeric.
Nope, because: > balance <- "fruit" > (!is.numeric(balance) && length(balance) != 1) [1] FALSE > (balance < 0) [1] FALSE > > ------------------------------ > > A second attempt, with my own code: > > setConstructorS3("StreamingFileReader", function(fileName, > hasHeader=T, sep="\t") { > if (missing (fileName)) throw ("Must supply a file name!"); > if (missing(hasHeader)) hasHeader <-T; > if (missing(sep)) sep="\t"; > > extend(Object(), "StreamingFileReader", > .fileName=fileName, > .hasHeader=hasHeader, > .sep=sep); > }) > > > z= StreamingFileReader("temp") > Error in list(`StreamingFileReader("temp")` = <environment>, > `extend(Object(), "StreamingFileReader", .fileName = > fileName, .hasHeader = hasHeader, .sep = sep)` = <environment>, : > > [2009-07-17 17:37:15] Exception: Must supply a file name! > at throw(Exception(...)) > at throw.default("Must supply a file name!") > at throw("Must supply a file name!") > at constructor() > at getStaticInstance.Class(class) > at getStaticInstance(class) > at getStaticInstance.Object(this) > at getStaticInstance(this) > at extend.Object(Object(), "StreamingFileReader", .fileName = > fileName, .hasHeader = hasHeader, .sep = > at extend(Object(), "StreamingFileReader", .fileName = > fileName, .hasHeader = hasHeader, .sep = sep) > at StreamingFileReader("temp") > > z= StreamingFileReader("temp") > > z$.fileName > [1] "temp" > > Why is it that the first time I try to construct the object it fails, > and the second time it seems to work just fine? Is there something I > should be doing between declaring the constructor and using the object > (besides adding S3 methods?) >From help(setConstructorS3): "Note: The constructor must be able to be called with no arguments, i.e. use default values for all arguments or make sure you use missing() or similar! ...". In your case you must design your constructor function so that you can call it without arguments, e.g. StreamingFileReader(). The reason for this is that a *static* instance of the class is always created automatically by calling the constructor with empty arguments. This static instance is create the first time the constructor is called in your code, but not the following times. This is why you only get the error the first time, but not in subsequent calls. This "feature" is by design of R.oo/setConstructorS3() - too long explanation/take my word on it. There should be no more surprises after this one (few people ever discover it). /Henrik > > Thanks for any help, I find this entirely confusing. > > -Jim Nemesh > > > > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. > ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.