---
title: "retListClasses"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{retListClasses}
  %\VignetteEngine{knitr::rmarkdown}
  %\usepackage[utf8]{inputenc}
---

## retList classes

`retList` can be used as a shortcut to:

```{r eval=FALSE}
constructor <- function(...) {
  ...
  out <- list(...)
  class(out) <- "constructor"
  out
}
```

vs. 

```{r eval=FALSE}
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: 

```{r}
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.

```{r}
ann <- Person("Ann")
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:

```{r}
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
p$name()
p$name("Paul")
p
```

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.

```{r}
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)
kalle
```
