1
1
# ' Create a new ggproto object
2
2
# '
3
- # ' ggproto is inspired by the proto package, but it has some important
4
- # ' differences. Notably, it cleanly supports cross-package inheritance, and has
5
- # ' faster performance.
3
+ # ' Construct a new object with \code{ggproto}, test with \code{is.proto},
4
+ # ' and access parent methods/fields with \code{ggproto_parent}.
6
5
# '
7
- # ' @section Calling ggproto methods:
6
+ # ' ggproto implements a protype based OO system which blurs the lines between
7
+ # ' classes and instances. It is inspired by the proto package, but it has some
8
+ # ' important differences. Notably, it cleanly supports cross-package
9
+ # ' inheritance, and has faster performance.
8
10
# '
11
+ # ' In most cases, creating a new OO system to be used by a single package is
12
+ # ' not a good idea. However, it was the least-bad solution for ggplot2 because
13
+ # ' it required the fewest changes to an already complex code base.
14
+ # '
15
+ # ' @section Calling methods:
9
16
# ' ggproto methods can take an optional \code{self} argument: if it is present,
10
17
# ' it is a regular method; if it's absent, it's a "static" method (i.e. it
11
18
# ' doesn't use any fields).
17
24
# ' in the function signature, although customarily it comes first.
18
25
# '
19
26
# ' @section Calling methods in a parent:
20
- # '
21
27
# ' To explicitly call a methods in a parent, use
22
28
# ' \code{ggproto_parent(Parent, self)}.
23
29
# '
24
30
# ' @param _class Class name to assign to the object. This is stored as the class
25
- # ' attribute of the object. If \code{NULL} (the default), no class name will
26
- # ' be added to the object.
27
- # ' @param _inherit ggproto object to inherit from. If \code{NULL}, don't inherit
28
- # ' from any object.
29
- # ' @param parent,self Access parent class \code{parent} of object \code{self}.
31
+ # ' attribute of the object. This is optional: if \code{NULL} (the default),
32
+ # ' no class name will be added to the object.
33
+ # ' @param _inherit ggproto object to inherit from. If \code{NULL}, don't
34
+ # ' inherit from any object.
30
35
# ' @param ... A list of members in the ggproto object.
31
36
# ' @export
37
+ # ' @examples
38
+ # ' Adder <- ggproto("Adder",
39
+ # ' x = 0,
40
+ # ' add = function(self, n) {
41
+ # ' self$x <- self$x + n
42
+ # ' self$x
43
+ # ' }
44
+ # ' )
45
+ # ' is.ggproto(Adder)
46
+ # '
47
+ # ' Adder$add(10)
48
+ # ' Adder$add(10)
49
+ # '
50
+ # ' Doubler <- ggproto("Doubler", Adder,
51
+ # ' add = function(self, n) {
52
+ # ' ggproto_parent(Adder, self)$add(n * 2)
53
+ # ' }
54
+ # ' )
55
+ # ' Doubler$x
56
+ # ' Doubler$add(10)
32
57
ggproto <- function (`_class` = NULL , `_inherit` = NULL , ... ) {
33
58
e <- new.env(parent = emptyenv())
34
59
@@ -65,10 +90,17 @@ ggproto <- function(`_class` = NULL, `_inherit` = NULL, ...) {
65
90
e
66
91
}
67
92
68
- # ' Is an object a ggproto object?
69
- # '
93
+
94
+ # ' @export
95
+ # ' @rdname ggproto
96
+ # ' @param parent,self Access parent class \code{parent} of object \code{self}.
97
+ ggproto_parent <- function (parent , self ) {
98
+ structure(list (parent = parent , self = self ), class = " ggproto_parent" )
99
+ }
100
+
70
101
# ' @param x An object to test.
71
102
# ' @export
103
+ # ' @rdname ggproto
72
104
is.ggproto <- function (x ) inherits(x , " ggproto" )
73
105
74
106
fetch_ggproto <- function (x , name ) {
@@ -98,12 +130,6 @@ fetch_ggproto <- function(x, name) {
98
130
res
99
131
}
100
132
101
- # ' @export
102
- # ' @rdname ggproto
103
- ggproto_parent <- function (parent , self ) {
104
- structure(list (parent = parent , self = self ), class = " ggproto_parent" )
105
- }
106
-
107
133
# ' @export
108
134
`$.ggproto` <- function (x , name ) {
109
135
res <- fetch_ggproto(x , name )
@@ -140,7 +166,6 @@ make_proto_method <- function(self, f) {
140
166
fun
141
167
}
142
168
143
-
144
169
# ' @export
145
170
`[[.ggproto` <- `$.ggproto`
146
171
@@ -153,6 +178,7 @@ make_proto_method <- function(self, f) {
153
178
# ' the returned list. If \code{FALSE}, do not include any inherited items.
154
179
# ' @param ... Further arguments to pass to \code{as.list.environment}.
155
180
# ' @export
181
+ # ' @keywords internal
156
182
as.list.ggproto <- function (x , inherit = TRUE , ... ) {
157
183
res <- list ()
158
184
@@ -169,7 +195,7 @@ as.list.ggproto <- function(x, inherit = TRUE, ...) {
169
195
}
170
196
171
197
172
- # ' Print a ggproto object
198
+ # ' Format or print a ggproto object
173
199
# '
174
200
# ' If a ggproto object has a \code{$print} method, this will call that method.
175
201
# ' Otherwise, it will print out the members of the object, and optionally, the
@@ -182,6 +208,14 @@ as.list.ggproto <- function(x, inherit = TRUE, ...) {
182
208
# ' will be passed to it. Otherwise, these arguments are unused.
183
209
# '
184
210
# ' @export
211
+ # ' @examples
212
+ # ' Dog <- ggproto(
213
+ # ' print = function(self, n) {
214
+ # ' cat("Woof!\n")
215
+ # ' }
216
+ # ' )
217
+ # ' Dog
218
+ # ' cat(format(Dog), "\n")
185
219
print.ggproto <- function (x , ... , flat = TRUE ) {
186
220
if (is.function(x $ print )) {
187
221
x $ print(... )
@@ -193,10 +227,8 @@ print.ggproto <- function(x, ..., flat = TRUE) {
193
227
}
194
228
195
229
196
- # ' Format a ggproto object
197
- # '
198
- # ' @inheritParams print.ggproto
199
230
# ' @export
231
+ # ' @rdname print.ggproto
200
232
format.ggproto <- function (x , ... , flat = TRUE ) {
201
233
classes_str <- function (obj ) {
202
234
classes <- setdiff(class(obj ), " ggproto" )
0 commit comments