Generic "classes" inside R
data-structures, generics, r, stack
Solution
This is a simpler version of the stack implementation @GSee references that avoids using any of the formal object-orientation systems available in R. Simplification proceeds from the fact that all functions in R are closures and functions created during a function call are bound to the environment created for that call.
new_stack <- function() {
stack <- vector()
push <- function(x) stack <<- c(stack, x)
pop <- function() {
tmp<-tail(stack, 1)
stack<<-stack[-length(stack)]
return(tmp)
}
structure(list(pop=pop, push=push), class='stack')
}
x <- new_stack()
x$push(1:3)
x$pop()
# [1] 3
x$pop()
# [1] 2
Here's an S4 implementation, for comparison.
setClass('Stack',
representation(list='list', cursor='numeric'), # type defs
prototype(list=list(), cursor=NA_real_)) # default values
setGeneric('push', function(obj, ...) standardGeneric('push'))
setMethod('push', signature(obj='Stack'),
function(obj, x) {
obj@list <- c(x, obj@list)
obj
})
setGeneric('pop', function(obj, ...) standardGeneric('pop'))
setMethod('pop', signature(obj='Stack'),
function(obj) {
obj@cursor <- obj@list[[1]]
obj@list <- obj@list[-1]
obj
}
)
x <- new('Stack')
# cursor is empty to start
x@cursor
#[1] NA
# add items
x <- push(x, 1)
x <- push(x, 2)
# pop them (move next item to cursor, remove from list)
x <- pop(x)
x@cursor
# [1] 2
x <- pop(x)
x@cursor
# [1] 1
Problem
I have written a stack "class" with the following functions: `add`, `push`, `pop`, `size`, `isEmpty`, `clear` (and some more). I'd like to use this "class" as a generic in R, so I may create multiple instances of stacks within my script. How do I go about doing this? (I have class in quotes because my stack functions are written in a different script (not necessarily the definition of a class per se) Thanks in advance ``` list <- "" cursor = 0 #Initializes stack to empty stack <- function(){ list <- c() cursor = -1 assign("list",list,.GlobalEnv) assign("cursor",cursor,.GlobalEnv) } #Where item is a item to be added to generic list push <- function(item){ if(size(list) == 0){ add(item, -1) }else{ add(item, 0) } assign("list",list,.GlobalEnv) } ```