Entornos como objetos
Parte de la sección Programación orientada a objetos del Journey de R de Coddy. Lección 18 de 57.
Un entorno es un conjunto de valores con nombre, como una lista, creado con new.env(). La diferencia es que un entorno nunca se copia: cada variable que hace referencia a él ve el mismo objeto, por lo que un cambio realizado a través de un nombre es visible a través de todos ellos:
e <- new.env()
e$count <- 1
alias <- e
alias$count <- 99
print(e$count)
l <- list(count = 1)
copy <- l
copy$count <- 99
print(l$count)Salida:
[1] 99
[1] 1Una función que recibe un entorno cambia el objeto de quien la llama. No tiene que devolver nada, y quien la llama no asigna un resultado:
deposit <- function(acc, x) acc$balance <- acc$balance + x
acc <- new.env()
acc$balance <- 10
deposit(acc, 5)
deposit(acc, 5)
print(acc$balance)Salida:
[1] 20assign(), get() y exists() funcionan con un nombre almacenado en una variable, y ls() enumera los nombres de un entorno en orden alfabético:
e <- new.env()
for (fruit in c("pear", "apple")) assign(fruit, nchar(fruit), envir = e)
print(ls(e))
print(get("pear", envir = e))
print(exists("kiwi", envir = e))Salida:
[1] "apple" "pear"
[1] 4
[1] FALSEAn environment con un atributo de clase es un objeto S3 con semántica de referencia: sus métodos funcionan como de costumbre, y las funciones que lo modifican lo hacen en el propio objeto:
new_wallet <- function(coins = 0) {
w <- new.env()
w$coins <- coins
class(w) <- "wallet"
w
}
print.wallet <- function(x, ...) {
cat("wallet with", x$coins, "coins\n")
invisible(x)
}
spend <- function(w, n) w$coins <- w$coins - n
w <- new_wallet(10)
spend(w, 3)
wSalida:
wallet with 7 coinsDesafío
FácilUn inventario es un entorno de clase inventory con una variable, items, un vector numérico con nombre que contiene las existencias. Completa Inventory.R:
new_inventory()crea el entorno con unitemsvacío (c()es suficiente) y la clase.add_stock(inv, item, n)añadena las existencias del artículo, empezando desde 0 para un artículo nuevo.take_stock(inv, item, n)eliminany devuelveTRUEcuando hay suficiente; de lo contrario, no cambia nada y devuelveFALSE.stock_of(inv, item)devuelve las existencias, 0 para un artículo desconocido.
Las funciones modifican el inventario directamente y no lo devuelven. El código proporcionado lee los comandos add apple 5 y take apple 2, imprime el resultado de cada operación take y, después, cada artículo en orden alfabético.
Tu código va en Inventory.R. main.R contiene el código proporcionado de entrada/salida y no se puede editar.
Pruébalo tú mismo
source("Inventory.R")
# Código de entrada/salida suministrado: déjalo como está
input <- suppressWarnings(readLines(file("stdin")))
inv <- new_inventory()
for (line in input) {
p <- strsplit(line, " ")[[1]]
n <- as.numeric(p[3])
if (p[1] == "add") add_stock(inv, p[2], n)
if (p[1] == "take") cat("take ", p[2], ": ", if (take_stock(inv, p[2], n)) "ok" else "not enough", "\n", sep = "")
}
for (item in sort(names(inv$items))) cat(item, ": ", stock_of(inv, item), "\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