Date: 2017-05-06

# retListClasses

#### 2017-05-06

## retList classes

`retList` can be used as a shortcut to:

    constructor <- function(...) {
      ...
      out <- list(...)
      class(out) <- "constructor"
      out
    }

vs.

    constructor <- function(...) {
      ...
      retList("constructor")
    }

It will simply find all objects in the environment in which it is called and returns those in a list. This is one way to think about and implement features associated with object orientation in R.

## Basics

Every value bound to a symbol will be public, objects with a leading dot in the name will be private. This can be changed by stating which names to make public explicitely.

Here is a simple class definition:

    library("aoos")

    Person <- function(name) {

      print <- function(x, ...) {
        cat(paste0("Hello, my name is ", .self$name, ".\n"))
      }

      retList(c("Person", "Print"))
    }

`retList` is used as a generic constructor function. It allways returns a list containing all visible values from the environment where it is called. There is a print method `print.Print` in the package which will look for a member function called print for printing. Thus the `print` method in the class Person will be used as S3 printing method.

    ann <- Person("Ann")
    ann

    ## Hello, my name is Ann.

Inside the class definition - i.e. the body of the constructor - you can use `.self` but you do not have to; It just might be more explicit. You can also use the super-assignment operator `<<-`. Note that `.self` is not a reference to the instance itself, it is only referencing to the environment in which the methods will live in.

You should keep in mind that a public field is a value in a list and not a reference to the value in `.self`. Thus, if your object should have public fields you have to define get/set methods. In this example you can think of `name` as an attribute since changing it in an instance won’t change the bahavior of `greet`. Here is something you can do instead:

    Person <- function(.name) {

      print <- function(x, ...) {
        cat(paste0("Hello, my name is ", .self$.name, ".\n"))
      }

      name <- function(x) {
        if (!missing(x)) .name <<- x
        .name
      }

      retList(c("Person", "Print"))
    }

    p <- Person("Ann")
    p

    ## Hello, my name is Ann.

    p$name()

    ## [1] "Ann"

    p$name("Paul")

    ## [1] "Paul"

    p

    ## Hello, my name is Paul.

Although I don’t understand why ‘Ann’ can change to be ‘Paul’, this is one way of adding something like reference semantics.

## Inheritance

An object can inherit from another object. The constructer then extends the instance of the super class/object. For that you can supply a call to the super classes constructor function, where you also have to supply arguments for initialization.

    Person <- function(name) {

      print <- function(x, ...) {
        cat(paste0("Hello, my name is ", .self$name, ".\n"))
      }

      retList(c("Person", "Print"))

    }

    Employee <- function(id, ...) {

      print <- function(x, ...) {
        cat("Name: ", name, "\nID:   ", id)
      }

      retList("Employee", super = Person(...))

    }

    kalle <- Employee("1", "Kalle")
    str(kalle)

    ## List of 3
    ##  $ id   : chr "1"
    ##  $ print:function (x, ...)
    ##   ..- attr(*, "srcref")=Class 'srcref'  atomic [1:8] 13 12 15 3 12 3 13 15
    ##   .. .. ..- attr(*, "srcfile")=Classes 'srcfilecopy', 'srcfile' <environment: 0x34fa818>
    ##  $ name : chr "Kalle"
    ##  - attr(*, ".self")=<environment: 0x44fc360>
    ##  - attr(*, "class")= chr [1:4] "Employee" "Person" "Print" "list"

    kalle

    ## Name:  Kalle
    ## ID:    1