[R] Help with R.oo

Henrik Bengtsson hb at stat.berkeley.edu
Sat Jul 18 03:21:29 CEST 2009


On Fri, Jul 17, 2009 at 11:41 PM, Jim Nemesh<nemesh at 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 at 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.
>




More information about the R-help mailing list