Menu
Coddy logo textTech

Métodos de impresión y formato

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

Cuando se imprime un valor, R llama a la función print(). Sin nada especial para la clase, un objeto S3 se imprime como su lista seguida del atributo de clase, lo que resulta difícil de leer:

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

Salida:

$amount
[1] 9.5

$currency
[1] "EUR"

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

Un método es una función llamada generic.class. Cuando print() recibe un objeto de la clase money, busca print.money() y lo llama en su lugar. Un método de impresión escribe con cat() y termina con invisible(x), por lo que devuelve el objeto sin imprimirlo una 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

Salida:

<money 9.5 EUR>
<money 9.5 EUR>

format() es el genérico para convertir un valor en texto. Un método format.money() devuelve el texto en lugar de imprimirlo, de modo que otro código pueda incluirlo en una oración y el método de impresión pueda reutilizarlo:

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

Salida:

Money: 9.50 EUR 
You owe 9.50 EUR 

Un método toma los mismos argumentos que su genérico. print() y format() se declaran como function(x, ...), por lo que sus métodos también comienzan con x, .... ... acepta argumentos adicionales, como digits, que quien realiza la llamada puede pasar. Los métodos funcionan dondequiera que se llame al genérico, por ejemplo, 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)))

Salida:

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

Desafío

Fácil

new_money() en Money.R ya está dada. Añade dos métodos al mismo archivo:

  • format.money(x, ...) devuelve el importe con dos decimales y la moneda: 9.50 EUR.
  • print.money(x, ...) imprime <money 9.50 EUR> en su propia línea, usando format(), y devuelve invisible(x).

El código proporcionado lee las líneas 9.5 EUR, imprime cada objeto monetario y después imprime list: con todos los importes formateados unidos por + .

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

Pruébalo tú mismo

source("Money.R")

# Código de entrada/salida suministrado: déjalo tal 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 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