From toth@dene@ @ending from kogentum@hu  Sun Sep  2 01:19:55 2018
From: toth@dene@ @ending from kogentum@hu (=?UTF-8?B?RMOpbmVzIFTDs3Ro?=)
Date: Sun, 2 Sep 2018 01:19:55 +0200
Subject: [Rd] True length - length(unclass(x)) - without having to call
 unclass()?
In-Reply-To: <CAFDcVCQdmLYM4gPj_zoz4KeoHGGUzJux9hLK_3vMVaeWUsrHQQ@mail.gmail.com>
References: <CAFDcVCQdmLYM4gPj_zoz4KeoHGGUzJux9hLK_3vMVaeWUsrHQQ@mail.gmail.com>
Message-ID: <d2733c97-5bec-dc0e-cb05-812b0cd63ff5@kogentum.hu>

The solution below introduces a dependency on data.table, but otherwise 
it does what you need:

---

# special method for Foo objects
length.Foo <- function(x) {
   length(unlist(x, recursive = TRUE, use.names = FALSE))
}

# an instance of a Foo object
x <- structure(list(a = 1, b = list(b1 = 1, b2 = 2)), class = "Foo")

# its length
stopifnot(length(x) == 3L)

# get its length as if it were a standard list
.length <- function(x) {
   cls <- class(x)
   # setattr() does not make a copy, but modifies by reference
   data.table::setattr(x, "class", NULL)
   # get the length
   len <- base::length(x)
   # re-set original classes
   data.table::setattr(x, "class", cls)
   # return the unclassed length
   len
}

# to check that we do not make unwanted changes
orig_class <- class(x)

# check that the address in RAM does not change
a1 <- data.table::address(x)

# 'unclassed' length
stopifnot(.length(x) == 2L)

# check that address is the same
stopifnot(a1 == data.table::address(x))

# check against original class
stopifnot(identical(orig_class, class(x)))

---


On 08/24/2018 07:55 PM, Henrik Bengtsson wrote:
> Is there a low-level function that returns the length of an object 'x'
> - the length that for instance .subset(x) and .subset2(x) see? An
> obvious candidate would be to use:
> 
> .length <- function(x) length(unclass(x))
> 
> However, I'm concerned that calling unclass(x) may trigger an
> expensive copy internally in some cases.  Is that concern unfounded?
> 
> Thxs,
> 
> Henrik
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>



[Rd] True length - length(unclass(x)) - without having to call unclass()?
=?UTF-8?B?RMOpbmVzIFTDs3Ro?=