Semántica de copia
Parte de la sección Programación orientada a objetos del Journey de R de Coddy. Lección 39 de 57.
Los objetos S3 y S4 son valores: una función que cambia uno cambia su propia copia. Los objetos RC son referencias: el objeto de quien llama cambia. La misma función se comporta de manera diferente para los dos tipos:
setClass("S4Box", slots = c(n = "numeric"))
RCBox <- setRefClass("RCBox", fields = list(n = "numeric"))
bump_s4 <- function(b) { b@n <- b@n + 1; invisible(b) }
bump_rc <- function(b) b$n <- b$n + 1
v <- new("S4Box", n = 1)
r <- RCBox$new(n = 1)
bump_s4(v)
bump_rc(r)
cat(v@n, r$n)Salida:
1 2$copy() crea un objeto nuevo e independiente con los mismos valores de campo. Cambiar la copia no afecta al original:
Account <- setRefClass("Account", fields = list(balance = "numeric"))
a <- Account$new(balance = 100)
alias <- a
backup <- a$copy()
alias$balance <- 0
cat(a$balance, backup$balance)Salida:
0 100Una lista puede contener el mismo objeto RC varias veces. Cambiar un elemento cambia entonces todos ellos. Crea un objeto nuevo para cada elemento cuando deban ser independientes:
Counter <- setRefClass("Counter", fields = list(n = "numeric"))
one <- Counter$new(n = 0)
same <- list(one, one, one)
same[[1]]$n <- 5
fresh <- lapply(1:3, function(i) Counter$new(n = 0))
fresh[[1]]$n <- 5
cat(same[[3]]$n, fresh[[3]]$n)Salida:
5 0identical(a, b) es TRUE para dos nombres del mismo objeto RC, y FALSE para una copia, incluso cuando los campos siguen siendo iguales:
Account <- setRefClass("Account", fields = list(balance = "numeric"))
a <- Account$new(balance = 100)
b <- a
c2 <- a$copy()
cat(identical(a, b), identical(a, c2), c2$balance == a$balance)Salida:
TRUE FALSE TRUEDesafío
FácilUn editor de texto mantiene puntos de guardado. Declara la clase de referencia Document en Document.R con el campo text (carácter) y un método type(s) que añade s al texto. Después escribe checkpoint(doc), que devuelve una copia independiente del documento.
La definición con métodos está envuelta en suppressMessages(). El código proporcionado comienza con un punto de guardado y después lee comandos: save almacena checkpoint(doc), undo vuelve a una copia del último punto de guardado y cualquier otra línea se escribe. Imprime el texto y el texto guardado después de cada comando, por lo que un punto de guardado nunca debe cambiar cuando se continúa escribiendo.
Tu código va en Document.R. main.R contiene el código de entrada/salida proporcionado y no se puede editar.
Pruébalo tú mismo
source("Document.R")
# Código de entrada/salida suministrado: mantenlo tal cual
input <- suppressWarnings(readLines(file("stdin")))
doc <- Document$new(text = "")
saved <- checkpoint(doc)
for (cmd in input) {
if (cmd == "save") {
saved <- checkpoint(doc)
} else if (cmd == "undo") {
doc <- checkpoint(saved)
} else {
doc$type(cmd)
}
cat(cmd, " -> [", doc$text, "] saved [", saved$text, "]\n", sep = "")
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación orientada a objetos
1Fundamentos de S3
Trabajar con archivosListas con una claseFunciones constructorasMétodos de impresión y formatoValidadores y auxiliaresRepaso: temperaturas4Encapsulación en R
Cierres como objetosEntornos como objetosFunciones de accesoProtección del estadoRepaso: parquímetro2S3 Genéricos y métodos
Genéricos y UseMethodMétodos predeterminadosMétodos para genéricos baseFundamentos de NextMethodRepaso: áreas de figuras5Clases S4
Definición de clases S4Slots y accesoComprobaciones de validezMétodos showRepaso - Catálogo de productos8Clases de referencia
Definición de clases de referenciaMétodos y actualizaciones de camposSemántica de copiaHerencia y callSuperRepaso: cola de tareas11Proyecto: Gestión de biblioteca
Libros y miembrosPréstamo de librosPractica por tu cuenta: Compilador de R online