Menu
Coddy logo textTech

Definición de clases de referencia

Parte de la sección Programación orientada a objetos del Journey de R de Coddy. Lección 37 de 57.

Clases de referencia (RC) son el sistema de R para objetos que cambian en el propio objeto, como en Java o Python. setRefClass() declara una clase con campos tipados y devuelve un generador; $new() crea un objeto, y $ lee y modifica sus campos:

Account <- setRefClass("Account", fields = list(owner = "character", balance = "numeric"))
a <- Account$new(owner = "Ada", balance = 100)
a$balance <- a$balance + 50
cat(a$owner, a$balance)

Salida:

Ada 150

Un objeto RC es una referencia, como un entorno. Asignarlo a otra variable o pasarlo a una función no lo copia, por lo que un cambio realizado a través de cualquier nombre es un cambio en el mismo objeto:

Account <- setRefClass("Account", fields = list(owner = "character", balance = "numeric"))
pay_fee <- function(acc) acc$balance <- acc$balance - 5
a <- Account$new(owner = "Ada", balance = 100)
b <- a
b$balance <- 60
pay_fee(a)
cat(a$balance, b$balance)

Salida:

55 55

Los campos tienen tipos. Se rechaza asignar un valor de la clase incorrecta y el campo conserva su valor anterior:

Account <- setRefClass("Account", fields = list(owner = "character", balance = "numeric"))
a <- Account$new(owner = "Ada", balance = 100)
msg <- tryCatch({ a$balance <- "lots"; "changed" }, error = function(e) conditionMessage(e))
cat(msg, "\n")
cat(a$balance, "\n")

Salida:

invalid assignment for reference class field ‘balance’, should be from class “numeric” or a subclass (was class “character”) 
100 

El generador describe la clase: Account$fields() enumera los campos y sus tipos. Un objeto impreso sin un método show enumera sus campos; un campo al que no se le asignó ningún valor está vacío:

Account <- setRefClass("Account", fields = list(owner = "character", balance = "numeric"))
print(Account$fields())
Account$new(owner = "Bo")

Salida:

      owner     balance 
"character"   "numeric" 
Reference class object of class "Account"
Field "owner":
[1] "Bo"
Field "balance":
numeric(0)
challenge icon

Desafío

Fácil

Declara la clase de referencia Book en Book.R con los campos title y author (carácter) y pages (numérico), y conserva el generador en Book. Después escribe add_pages(book, n), que suma n a las páginas del libro directamente y no devuelve nada útil.

El código proporcionado lee title;author;pages, crea el libro, lo asigna a una segunda variable, suma los números restantes mediante ese segundo nombre e imprime el libro original y los nombres de los campos.

Tu código debe ir en Book.R. main.R contiene el código proporcionado de entrada/salida y no se puede editar.

Pruébalo tú mismo

source("Book.R")

# Código de entrada/salida suministrado: mantenlo tal como está
input <- suppressWarnings(readLines(file("stdin")))
p <- strsplit(input[1], ";")[[1]]
b <- Book$new(title = p[1], author = p[2], pages = as.numeric(p[3]))
alias <- b
for (n in as.numeric(input[-1])) add_pages(alias, n)
cat(b$title, " by ", b$author, ": ", b$pages, " pages\n", sep = "")
cat("fields: ", paste(names(Book$fields()), collapse = ", "), "\n", sep = "")
quiz iconPonte a prueba

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

Practica por tu cuenta: Compilador de R online