In R we need to introduce S3 classes to sort custom objects (see eg. this answer). For my R package I've introduced a couple of S3 classes and successfully managed to get my objects sorted.
I'd like to extend a certain function such that it is also able to receive custom data from the user, for which they are also able to supply their own compare function (instead of going through their own create-an-S3-class ordeal).
The following seems to work... sort of.
# Try 1
mySort <- function(someList, compare) {
local({
`[.tmpclass` <- function(x, i, ...) structure(unclass(x)[i], class = "tmpclass")
`==.tmpclass` <- function(a, b) compare(a[[1]],b[[1]]) == 0
`>.tmpclass` <- function(a, b) compare(a[[1]],b[[1]]) > 0
is.na.tmpclass <- function(x) FALSE
class(someList) <- "tmpclass"
sort(someList)
})
}
# Try 2
mySort <- function(someList, compare) {
local({
class(someList) <- "tmpclass"
sort(someList)
}, envir = list(
`[.tmpclass` <- function(x, i, ...) structure(unclass(x)[i], class = "tmpclass"),
`==.tmpclass` <- function(a, b) compare(a[[1]],b[[1]]) == 0,
`>.tmpclass` <- function(a, b) compare(a[[1]],b[[1]]) > 0,
is.na.tmpclass <- function(x) FALSE
))
}
l <- list("hello", "world", "how", "is", "everything")
# sort by char length
mySort(l, compare = function(a,b) nchar(a) - nchar(b))
If I debug right before the sort call, everything seems to work fine (see screenshot below, debugging in line 133 before calling sort). I can call someList[3] > someList[4] and get the expected result. However once sort is called, this information seems to be lost as I get the following error message: unimplemented type 'list' in 'greater'.
Please note that the implementation works if I just add the class normally to the global environment.
Is there some way to trick R into temporarily learning about an S3 class that ought to be sorted?