Ambientes como Objetos
Parte da seção Programação Orientada a Objetos do Journey de R da Coddy. Lição 18 de 57.
Um ambiente é um conjunto de valores nomeados, como uma lista, criado com new.env(). A diferença é que um ambiente nunca é copiado: toda variável que faz referência a ele vê o mesmo objeto, portanto uma alteração feita por meio de um nome fica visível por meio de todos eles:
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)Saída:
[1] 99
[1] 1Uma função que recebe um ambiente altera o objeto do chamador. Ela não precisa retornar nada, e o chamador não atribui um 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)Saída:
[1] 20assign(), get() e exists() funcionam com um nome armazenado em uma variável, e ls() lista os nomes em um ambiente em ordem classificada:
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))Saída:
[1] "apple" "pear"
[1] 4
[1] FALSEUm ambiente com um atributo de classe é um objeto S3 com semântica de referência: seus métodos funcionam normalmente, e as funções que o modificam fazem isso no próprio 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)
wSaída:
wallet with 7 coinsDesafio
FácilUm inventário é um ambiente da classe inventory com uma variável, items, um vetor numérico nomeado de estoque. Complete Inventory.R:
new_inventory()cria o ambiente com umitemsvazio (c()serve) e a classe.add_stock(inv, item, n)adicionanao estoque do item, começando em 0 para um item novo.take_stock(inv, item, n)removene retornaTRUEquando há quantidade suficiente; caso contrário, não altera nada e retornaFALSE.stock_of(inv, item)retorna o estoque, 0 para um item desconhecido.
As funções alteram o inventário diretamente e não o retornam. O código fornecido lê os comandos add apple 5 e take apple 2, imprime o resultado de cada take e, em seguida, cada item em ordem alfabética.
Seu código deve ficar em Inventory.R. main.R contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
source("Inventory.R")
# Código de entrada/saída fornecido: mantenha-o 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 lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos do S3
Trabalhando com ArquivosListas com uma ClasseFunções ConstrutorasMétodos de Impressão e FormataçãoValidadores e AuxiliaresRevisão - Temperaturas4Encapsulamento em R
Closures como ObjetosAmbientes como ObjetosFunções de AcessoProtegendo o EstadoRecapitulação - Parquímetro2Genéricos e Métodos S3
Genéricos e UseMethodMétodos padrãoMétodos para genéricos baseFundamentos de NextMethodRevisão - Áreas de formas5Classes S4
Definindo classes S4Slots e acessoVerificações de validadeMétodos showRevisão - Catálogo de produtos8Classes de Referência
Definindo Classes de ReferênciaMétodos e Atualizações de CamposSemântica de CópiaHerança e callSuperRecapitulação — Fila de Tarefas11Projeto: Gerenciamento de Biblioteca
Livros e MembrosEmpréstimo de LivrosPratique por conta própria: Compilador de R online