A toy package designed to showcase and serve as a reference/tutorial for S7 development. To be used in conjunction with the S7 package webs
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Changed code blocks

Should get syntax highlighting now

+9 -9
+9 -9
README.md
··· 39 39 40 40 S7 marries (most of) the flexibility of S3 with (most of) the formality of S4. I find it strikes a perfect middle ground which makes it easier to dictate and understand what objects of type `<T>` can and can't do. S7 is elegantly formal. I first encountered S3 when speaking to Dr Bodwin; the topic came up somehow and she showed me how simple and flexible S3 is with an example, something like: 41 41 42 - ```{r} 42 + ```r 43 43 x <- 1:10 44 44 class(x) <- "test" 45 45 mean.test <- function(x){ ··· 52 52 53 53 I was shocked at how easy it was to defined a class and write its method for a generic, especially since my knowledge of OOP was mostly in Java (which is very verbose). The flexibility offers a lot of obvious benefits, but it does come with some drawbacks. Firstly, I think it can be a bit hard to understand; I still find S3 object construction a bit strange. For example, if I wanted to skip `x`'s declaration, I could've written instead: 54 54 55 - ```{r} 55 + ```r 56 56 mean.test <- function(x){ 57 57 "HELLO WORLD" 58 58 } ··· 64 64 65 65 S7 may be formal, but it is also elegant–there are nice design patterns that can be implemented effortlessly. Take, for example, this implementation of some `Shape`s. 66 66 67 - ```{r} 67 + ```r 68 68 library(S7) 69 69 70 70 Shape <- new_class("Shape", abstract = TRUE) ··· 97 97 98 98 It can easily be extended to admit a `Square` class: 99 99 100 - ```{r} 100 + ```r 101 101 Square <- new_class("Square", 102 102 Rect, 103 103 constructor = function(side) { ··· 111 111 112 112 And, more usefully, our classes can be (minimally) changed to guarantee that the provided values are positive–being numeric is already ensured by using `class_numeric`, even in the original definitions. 113 113 114 - ```{r} 114 + ```r 115 115 positive_numeric <- new_property(class_numeric, 116 116 validator = function(value) { 117 117 if (value <= 0) "must be greater than 0" ··· 150 150 151 151 We could also compute area in a property instead of a method: 152 152 153 - ```{r} 153 + ```r 154 154 positive_numeric <- new_property(class_numeric, 155 155 validator = function(value) { 156 156 if (value <= 0) "must be greater than 0" ··· 217 217 218 218 You can set read only properties with S7, which you can observe in the package (properties in ALLCAPS are constants or "final".) That is a very nice way to expose values which you wish users to be aware of but don't want to mess with, like the value of a linked list node. 219 219 220 - ```{r} 220 + ```r 221 221 # https://rconsortium.github.io/S7/articles/classes-objects.html#frozen-properties 222 222 eg <- new_class("eg", 223 223 properties = list( ··· 243 243 244 244 You can, of course, bypass this: 245 245 246 - ```{r} 246 + ```r 247 247 attr(tmp, "VALUE") <- 1 248 248 tmp 249 249 #> <eg> ··· 258 258 259 259 I don't think you can't easily do anything like this in S7 ([yet](https://github.com/RConsortium/S7/issues/515)): 260 260 261 - ```{r} 261 + ```r 262 262 function(...){ 263 263 structure(..., class = "test") 264 264 }