I'm trying to avoid repetition inside an R6 object. There are calculated/derived values that must be updated each time one of the inputs is updated.
The Cube
object below demonstrates the problem. If I update any of width
, height
or depth
, it follows that volume
must be updated.
In this case, the formula is trivial, but in real-world cases that won't always be the case. It is possible to store the knowledge of volCalc
someplace, and to allow set_width
to use that function to update volume
when they are updated?
Right now, i can create the object using the object code below:
R> cc <- Cube$new(width = 5, height = 6, depth = 7)
but it breaks on update
R> cc$set_width(10)
Error in volCalc(self$width, self$height, self$depth) :
could not find function "volCalc"
As you can see, I put the knowledge of how to calculate the volume of a cube (volCalc
) in two places; but alas cc$set_width
and friends cannot find it...
Cube <- R6Class("Cube",
public = list(
width = NULL,
height = NULL,
depth = NULL,
volume = NULL,
initialize = function(width, height, depth) {
self$width <- width
self$height <- height
self$depth <- depth
volCalc = function(W, H, D) W * H * D
self$volume <- volCalc(width, height, depth)
},
volCalc = function(W, H, D) {
self$volume <- W * H * D
invisible(self)
},
set_width = function(nWidth) {
self$width <- nWidth
volCalc(self$width, self$height, self$depth)
invisible(self)
},
set_height = function(nHeight) {
self$height <- nHeight
volCalc(self$height, self$height, self$depth)
invisible(self)
},
set_depth = function(nDepth) {
self$depth <- nDepth
volCalc(self$depth, self$depth, self$depth)
invisible(self)
}
)
)
You need to tell your class where to find volCalc
. It will find it in self
. So all you need to do is make the internal calls to volCalc
be self$volCalc
. Then you can do this:
cc <- Cube$new(width = 5, height = 6, depth = 7)
cc
#> <Cube>
#> Public:
#> clone: function (deep = FALSE)
#> depth: 7
#> height: 6
#> initialize: function (width, height, depth)
#> set_depth: function (nDepth)
#> set_height: function (nHeight)
#> set_width: function (nWidth)
#> volCalc: function (W, H, D)
#> volume: 210
#> width: 5
cc$set_width(10)
cc
#> <Cube>
#> Public:
#> clone: function (deep = FALSE)
#> depth: 7
#> height: 6
#> initialize: function (width, height, depth)
#> set_depth: function (nDepth)
#> set_height: function (nHeight)
#> set_width: function (nWidth)
#> volCalc: function (W, H, D)
#> volume: 420
#> width: 10