Menu
Coddy logo textTech

Métodos de Impressão e Formatação

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

Quando um valor é impresso, R chama a função print(). Sem nada específico para a classe, um objeto S3 é impresso como sua lista seguida pelo atributo de classe, o que é difícil de ler:

m <- structure(list(amount = 9.5, currency = "EUR"), class = "money")
print(m)

Saída:

$amount
[1] 9.5

$currency
[1] "EUR"

attr(,"class")
[1] "money"

Um método é uma função chamada generic.class. Quando print() recebe um objeto da classe money, ele procura por print.money() e a chama em seu lugar. Um método de impressão escreve com cat() e termina com invisible(x), portanto retorna o objeto sem imprimi-lo uma segunda vez:

print.money <- function(x, ...) {
  cat("<money ", x$amount, " ", x$currency, ">\n", sep = "")
  invisible(x)
}
m <- structure(list(amount = 9.5, currency = "EUR"), class = "money")
print(m)
m

Saída:

<money 9.5 EUR>
<money 9.5 EUR>

format() é o genérico para transformar um valor em texto. Um método format.money() retorna o texto em vez de imprimi-lo, para que outro código possa inseri-lo em uma frase, e o método de impressão possa reutilizá-lo:

format.money <- function(x, ...) {
  sprintf("%.2f %s", x$amount, x$currency)
}
print.money <- function(x, ...) {
  cat("Money:", format(x), "\n")
  invisible(x)
}
m <- structure(list(amount = 9.5, currency = "EUR"), class = "money")
m
cat("You owe", format(m), "\n")

Saída:

Money: 9.50 EUR 
You owe 9.50 EUR 

Um método recebe os mesmos argumentos que seu genérico. print() e format() são declarados como function(x, ...), portanto seus métodos também começam com x, .... O ... aceita argumentos extras, como digits, que quem chama pode passar. Os métodos funcionam onde quer que o genérico seja chamado, por exemplo, dentro de vapply():

format.money <- function(x, ...) sprintf("%.2f %s", x$amount, x$currency)
wallet <- list(
  structure(list(amount = 3, currency = "EUR"), class = "money"),
  structure(list(amount = 0.5, currency = "USD"), class = "money")
)
print(vapply(wallet, format, character(1)))

Saída:

[1] "3.00 EUR" "0.50 USD"
challenge icon

Desafio

Fácil

new_money() em Money.R é fornecida. Adicione dois métodos ao mesmo arquivo:

  • format.money(x, ...) retorna o valor com duas casas decimais e a moeda: 9.50 EUR.
  • print.money(x, ...) imprime <money 9.50 EUR> em sua própria linha, usando format(), e retorna invisible(x).

O código fornecido lê as linhas 9.5 EUR, imprime cada objeto monetário e, em seguida, imprime list: com todos os valores formatados unidos por + .

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

Experimente você mesmo

source("Money.R")

# Código de entrada/saída fornecido: mantenha-o como está
input <- suppressWarnings(readLines(file("stdin")))
all <- list()
for (line in input) {
  p <- strsplit(line, " ")[[1]]
  m <- new_money(as.numeric(p[1]), p[2])
  print(m)
  all[[length(all) + 1]] <- m
}
cat("list: ", paste(vapply(all, format, character(1)), 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