From ggrothendieck at gmail.com  Tue Jan  8 02:56:24 2008
From: ggrothendieck at gmail.com (Gabor Grothendieck)
Date: Mon, 7 Jan 2008 20:56:24 -0500
Subject: [Rd] S3 vs S4 for a simple package
In-Reply-To: <47827EA9.8080802@r-project.org>
References: <CB8F09FF-2B71-4A19-BA7D-61CF056E4C22@noc.soton.ac.uk>
	<Pine.LNX.4.64.0801070908360.11790@gannet.stats.ox.ac.uk>
	<47827EA9.8080802@r-project.org>
Message-ID: <971536df0801071756u3ead0a72h8d98408bb723554@mail.gmail.com>

On Jan 7, 2008 2:34 PM, John Chambers <jmc at r-project.org> wrote:
> One thing you cannot do in S3 is to have methods that depend on anything
> but the first argument.

Actually, you can.  Here are two examples.

> ### first example - Axis ###
> ### note that it can be dispatched on x or at
> Axis
function (x = NULL, at = NULL, ..., side, labels = NULL)
{
    if (!is.null(x))
        UseMethod("Axis", x)
    else if (!is.null(at))
        UseMethod("Axis", at)
    else axis(side = side, at = at, labels = labels, ...)
}
<environment: namespace:graphics>

> ### second example: +.Date
> methods("+")  # note S3 Date method for +
[1] +.Date   +.POSIXt
> debug("+.Date")  # notify if +.Date invoked
> Sys.Date() + 1 # yup.  its invoked.
debugging in: `+.Date`(Sys.Date(), 1)
debug: {
    coerceTimeUnit <- function(x) {
        round(switch(attr(x, "units"), secs = x/86400, mins = x/1440,
            hours = x/24, days = x, weeks = 7 * x))
    }
    if (nargs() == 1)
        return(e1)
    if (inherits(e1, "Date") && inherits(e2, "Date"))
        stop("binary + is not defined for Date objects")
    if (inherits(e1, "difftime"))
        e1 <- coerceTimeUnit(e1)
    if (inherits(e2, "difftime"))
        e2 <- coerceTimeUnit(e2)
    structure(unclass(e1) + unclass(e2), class = "Date")
}
Browse[1]> Q
> 1 + Sys.Date()  # its invoked on arg 2 as well
debugging in: `+.Date`(1, Sys.Date())
debug: {
    coerceTimeUnit <- function(x) {
        round(switch(attr(x, "units"), secs = x/86400, mins = x/1440,
            hours = x/24, days = x, weeks = 7 * x))
    }
    if (nargs() == 1)
        return(e1)
    if (inherits(e1, "Date") && inherits(e2, "Date"))
        stop("binary + is not defined for Date objects")
    if (inherits(e1, "difftime"))
        e1 <- coerceTimeUnit(e1)
    if (inherits(e2, "difftime"))
        e2 <- coerceTimeUnit(e2)
    structure(unclass(e1) + unclass(e2), class = "Date")
}
Browse[1]> Q



[Rd] S3 vs S4 for a simple package
Gabor Grothendieck