Menu
Coddy logo textTech

Métodos y actualizaciones de campos

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

Los métodos van en la lista methods de setRefClass(). Dentro de un método, los campos son nombres simples, y <<- cambia un campo. En el ejecutor de Coddy, R imprime una nota sobre el paquete opcional codetools cuando se define una clase con métodos, así que incluye la definición en suppressMessages():

Counter <- suppressMessages(setRefClass("Counter",
  fields = list(count = "numeric"),
  methods = list(
    add = function(n = 1) {
      count <<- count + n
    },
    report = function() paste("count is", count)
  )
))
c1 <- Counter$new(count = 0)
c1$add()
c1$add(5)
print(c1$report())

Salida:

[1] "count is 6"

.self es el objeto sobre el que se llamó al método. Un método que termina con invisible(.self) devuelve el objeto, por lo que las llamadas se pueden encadenar:

Counter <- suppressMessages(setRefClass("Counter",
  fields = list(count = "numeric"),
  methods = list(
    add = function(n = 1) {
      count <<- count + n
      invisible(.self)
    }
  )
))
c1 <- Counter$new(count = 0)
c1$add(2)$add(3)$add(4)
print(c1$count)

Salida:

[1] 9

El método initialize se ejecuta dentro de $new(). initFields(...) establece los campos que se pasaron; después, el método puede asignar valores predeterminados a los demás. Los métodos se llaman entre sí por nombre:

Account <- suppressMessages(setRefClass("Account",
  fields = list(owner = "character", balance = "numeric"),
  methods = list(
    initialize = function(...) {
      initFields(...)
      if (length(balance) == 0) balance <<- 0
      invisible(.self)
    },
    deposit = function(x) balance <<- balance + x,
    deposit_twice = function(x) {
      deposit(x)
      deposit(x)
    }
  )
))
a <- Account$new(owner = "Ada")
a$deposit_twice(10)
print(a$balance)

Salida:

[1] 20

Dentro de un método, un <- simple aplicado a un nombre de campo crea una variable local con ese nombre y deja el campo sin cambios. Usa <<- para cada cambio de un campo:

Counter <- suppressMessages(setRefClass("Counter",
  fields = list(count = "numeric"),
  methods = list(
    broken = function() count <- count + 1,
    working = function() count <<- count + 1
  )
))
c1 <- Counter$new(count = 0)
c1$broken()
c1$broken()
c1$working()
print(c1$count)

Salida:

[1] 1
challenge icon

Desafío

Fácil

Completa la clase de referencia Stack en Stack.R. Mantiene sus elementos en el campo items (de tipo carácter, con el elemento superior al final) y tiene cuatro métodos:

  • push(x) añade x en la parte superior y devuelve invisible(.self), para que las inserciones puedan encadenarse;
  • pop() elimina y devuelve el elemento superior, o devuelve nothing cuando la pila está vacía;
  • peek() devuelve el elemento superior sin eliminarlo, o nothing;
  • size() devuelve el número de elementos.

La definición ya está envuelta en suppressMessages(). El código proporcionado lee los comandos push a b, pop y peek, después inserta dos elementos más en una llamada encadenada e imprime el tamaño.

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

Pruébalo tú mismo

source("Stack.R")

# Código de entrada/salida suministrado: déjalo tal como está
input <- suppressWarnings(readLines(file("stdin")))
s <- Stack$new()
for (cmd in input) {
  if (startsWith(cmd, "push ")) {
    items <- strsplit(substring(cmd, 6), " ")[[1]]
    for (it in items) s$push(it)
  } else if (cmd == "pop") {
    cat("popped ", s$pop(), "\n", sep = "")
  } else if (cmd == "peek") {
    cat("top ", s$peek(), "\n", sep = "")
  }
}
s$push("x")$push("y")
cat("size after two chained pushes: ", s$size(), "\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