Menu
Coddy logo textTech

Definindo Classes de Referência

Parte da seção Programação Orientada a Objetos do Journey de R da Coddy. Lição 37 de 57.

Classes de Referência (RC) são o sistema do R para objetos que mudam no próprio local, como em Java ou Python. setRefClass() declara uma classe com campos tipados e retorna um gerador; $new() cria um objeto, e $ lê e altera seus 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)

Saída:

Ada 150

Um objeto RC é uma referência, como um ambiente. Atribuí-lo a outra variável ou passá-lo para uma função não cria uma cópia, portanto uma alteração feita por qualquer nome é uma alteração no mesmo 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)

Saída:

55 55

Os campos têm tipos. A atribuição de um valor da classe errada é recusada, e o campo mantém seu valor antigo:

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")

Saída:

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

O gerador descreve a classe: Account$fields() lista os campos e seus tipos. Um objeto impresso sem um método show lista seus campos; um campo ao qual não foi atribuído um valor fica vazio:

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

Saída:

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

Desafio

Fácil

Declare a Classe de Referência Book em Book.R com os campos title e author (character) e pages (numeric), e mantenha o gerador em Book. Em seguida, escreva add_pages(book, n), que adiciona n às páginas do livro no próprio objeto e não retorna nada útil.

O código fornecido lê title;author;pages, cria o livro, atribui-o a uma segunda variável, adiciona os números restantes por meio desse segundo nome e imprime o livro original e os nomes dos campos.

Seu código deve ficar em Book.R. main.R contém o código fornecido de entrada/saída e não pode ser editado.

Experimente você mesmo

source("Book.R")

# Código de entrada/saída fornecido: mantenha-o 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 iconTeste seus conhecimentos

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

Pratique por conta própria: Compilador de R online