52 lines
1.4 KiB
R
52 lines
1.4 KiB
R
mEditor <- setRefClass("matrixEditor",
|
|
fields = list( data = "matrix",
|
|
edits = "list"),
|
|
methods = list(
|
|
edit = function(i, j, value) {
|
|
## the following string documents the edit method
|
|
'Replaces the range [i, j] of the
|
|
object by value.
|
|
'
|
|
backup <-
|
|
list(i, j, data[i,j])
|
|
data[i,j] <<- value
|
|
edits <<- c(edits, list(backup))
|
|
invisible(value)
|
|
},
|
|
undo = function() {
|
|
'Undoes the last edit() operation
|
|
and update the edits field accordingly.
|
|
'
|
|
prev <- edits
|
|
if(length(prev)) prev <- prev[[length(prev)]]
|
|
else stop("No more edits to undo")
|
|
edit(prev[[1]], prev[[2]], prev[[3]])
|
|
## trim the edits list
|
|
length(edits) <<- length(edits) - 2
|
|
invisible(prev)
|
|
}
|
|
))
|
|
|
|
xMat <- xEdited <- matrix(as.double(1:12),4,3)
|
|
xEdited[[2,2]] <- 0
|
|
xx <- mEditor$new(data = xMat)
|
|
xx$edit(2, 2, 0)
|
|
stopifnot(identical(xx$data, xEdited))
|
|
xEdited[[1,3]] <- -1
|
|
xx$edit(1,3, -1)
|
|
stopifnot(identical(xx$data, xEdited))
|
|
xx$undo()
|
|
xEdited[[1,3]] <- xMat[[1,3]]
|
|
stopifnot(identical(xx$data, xEdited))
|
|
xx$undo()
|
|
stopifnot(identical(xx$data, xMat))
|
|
|
|
## the tracing method
|
|
xx$trace(edit, quote(value <- 0))
|
|
xx$edit(2,2, -1) # traced should assign 0
|
|
stopifnot(identical(xx$data, xEdited))
|
|
xx$untrace(edit)
|
|
xx$edit(1, 3, -1) # now it should use -1
|
|
xEdited[[1,3]] <- -1
|
|
stopifnot(identical(xx$data, xEdited))
|