5

I'd like to define a new object class in R that comes with own functionality (e.g. getter for maximum value). Is it possible to realize this in R? I was thinking of something like:

test <- class() {
  len = 0     # object variable1

  __constructor(length=0) {
    len = length # set len
  }

  getLength <- function() {
    len   # return len
  }
}

and

ob = test(20)    # create Objectof class test
ob.getLength()   # get Length-Value of Object
R_User
  • 10,682
  • 25
  • 79
  • 120
  • 2
    Maybe you should read the "object oriented programming" section of the devtools wiki : https://github.com/hadley/devtools/wiki – juba Mar 06 '13 at 09:54
  • 4
    R has `S3`, `S4` an `R5` concepts of OOPs. You'll have to choose one and then define your own functions (S3) or methods (S4,R5). Start [**here**](https://github.com/hadley/devtools/wiki/S3) – Arun Mar 06 '13 at 09:55
  • ...related: http://stackoverflow.com/questions/9521651/r-and-object-oriented-programming – Paul Hiemstra Mar 06 '13 at 10:03

2 Answers2

8

To get you started, I'll give an example with S3 classes:

# create an S3 class using setClass:
setClass("S3_class", representation("list"))
# create an object of S3_class
S3_obj <- new("S3_class", list(x=sample(10), y=sample(10)))

Now, you can function-overload internal functions, for example, length function to your class as (you can also operator-overload):

length.S3_class <- function(x) sapply(x, length)
# which allows you to do:
length(S3_obj)

#  x  y 
# 10 10 

Or alternatively, you can have your own function with whatever name, where you can check if the object is of class S3_class and do something:

len <- function(x) { 
    if (class(x) != "S3_class") {
        stop("object not of class S3_class")
    }
    sapply(x, length)
}

> len(S3_obj)
#  x  y 
# 10 10 

> len(1:10)
# Error in len(1:10) : object not of class S3_class

It is a bit hard to explain S4 (like S3) as there are quite a bit of terms and things to know of (they are not difficult, just different). I suggest you go through the links provided under comments for those (and for S3 as well, as my purpose here was to show you an example of how it's done).

Arun
  • 116,683
  • 26
  • 284
  • 387
6

R also has function closures, which fits your example quite nicely

test = function() {
  len = 0
  set_length = function(l = 0) len <<-l
  get_length = function() len
  return(list(set_length=set_length, get_length=get_length))
}

this gives:

R> m = test()
R> m$set_length(10)
R> m$get_length()
[1] 10
R> m$set_length()
R> m$get_length()
[1] 0
csgillespie
  • 59,189
  • 14
  • 150
  • 185