forked from lgatto/2017-04-03-adv-r-progr-EMBL
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rc.Rmd
81 lines (61 loc) · 2.53 KB
/
rc.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
---
output: md_document
---
# Reference classes OOP
Reference classes are a Java-like class system (no generics!) implementation in R.
Reference classes use pass-by-reference logic that is different from the usual pass-by-value logic R uses. This means when we assign `a=b` both `a` and `b` point to the same object, and changing `a` will also modify `b` and vica versa.
## Creating classes
Similar syntax as S4, but now slots are called fields, and `setRefClass` returns a constructor object.
```{r}
Seq <- setRefClass("Seq",
fields = list(
name = "character",
alphabet = "character",
sequence = "character"))
```
We then use the constuctor to create objects:
```{r}
a = Seq(name="My seq", alphabet=c("A", "T"), sequence="ATTTTAAAAAA")
a
```
## Defining methods
Methods are defined either with the class, or later by modifying the constructor object.
```{r}
Seq <- setRefClass("Seq",
fields = list(
name = "character",
alphabet = "character",
sequence = "character"),
methods = list(
comp = function() {
"Complements the (DNA) sequence" ## inline docs
sequence <<- chartr("ACGT","TGCA",.self$sequence)
name <<- paste(.self$name, "-- complemented")
}
## there can be more, of course
))
```
A couple of things to note here:
- accessing fields and calling methods is done with the `$` operator.
- the current object can be referred to in a method by the reserved name `.self`.
- Changing fields of an object within methods needs to be done with the `<<-` operator.
Calling a method on the object will modify it:
```{r}
s <- Seq$new(name="foo", sequence="GATCATCA")
s
s$sequence
s$comp()
s$sequence
```
Objects are copied by reference and not value:
```{r}
s2 = s
s$sequence
s2$sequence
s$sequence = "ATTTA"
s$sequence
s2$sequence
```
# Summary
Reference classes are suitable for objects that are dynamically tracked by all the code: GUI components, read-only access to files (streams, data bases), internet resources, editing facilities, ... Because they are passed by reference they are _never_ copied, which means they are never duplicated in memory.
Because of their pass-by-reference semantics they are not appropriate as a replacement for S3 and S4 as this would lead to a lot of unanticipated side effects.