From murdoch.duncan at gmail.com  Mon Nov 17 02:14:02 2014
From: murdoch.duncan at gmail.com (Duncan Murdoch)
Date: Sun, 16 Nov 2014 20:14:02 -0500
Subject: [Rd] common base functions stripping S3 class
In-Reply-To: <CA+YV+Hx1qA_+JZ1QLo0D7Ckcc3A2sxa-ScAs5g44icfiO4DpnQ@mail.gmail.com>
References: <CA+YV+Hx1qA_+JZ1QLo0D7Ckcc3A2sxa-ScAs5g44icfiO4DpnQ@mail.gmail.com>
Message-ID: <54694BDA.10102@gmail.com>

On 16/11/2014, 7:58 PM, Murat Tasan wrote:
> Hi all --- this is less a specific question and more general regarding
> S3 classes.
> I've noticed that quite a few very common default implementations of
> generic functions (e.g. `unique`, `[`, `as.data.frame`) strip away
> class information.
> In some cases, it appears conditionals have been created to re-assign
> the class, but only for a few special types.
> For example, in `unique.default`, if the argument inherits (_only_)
> from "POSIXct" or "Date", the initial class is re-assigned to the
> returned object.
> But for any other custom S3 classes, it means we have to catch these
> frequent cases and write a lot relatively plain wrappers, e.g.:
> 
> unique.MyClass <- function(x, incomparables = FALSE, ...) {
>     structure(unique(unclass(x)), class = class(x))
> }
> 
> It's certainly nice to be able to create a very simple wrapper class
> on a base type, so that we can override common functions like plot(x).
> (An example is a simple class attribute that dictates a particular
> plot style for a vector of integers.)
> But it would be even nicer to not have to detect and override all the
> un-class events that occur when manipulating these objects with
> everyday functions, e.g. when adding that 'classed' integer vector to
> a data frame.
> 
> Apart from moving to S4 classes, how have most dealt with this?
> Might there be a list of common functions for which the default
> implementation strips class information?
> (Such a list could be a handy "consider overriding _this_" guide for
> implementors of any new classes.)
> 
> Cheers and thanks for any tips!

I don't know of such a list.  If I define a class, I wouldn't assume
that any functions preserve it, unless I specifically write them to do so.

Generally the idea is that the class should be stripped because R has no
way of knowing if the new object, for example unique(obj), still has the
necessary properties to be considered to be of the same class as obj.
Only the author of the class knows that.  S4 would help a bit here, but
only structurally (it could detect when the object couldn't possibly be
of the right class), not semantically.

Duncan Murdoch



[Rd] common base functions stripping S3 class
Duncan Murdoch