Menu
Coddy logo textTech

Métodos e Atualizações de Campos

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

Os métodos ficam na lista methods de setRefClass(). Dentro de um método, os campos são nomes simples, e <<- altera um campo. No executor do Coddy, R imprime uma observação sobre o pacote opcional codetools quando uma classe com métodos é definida; por isso, envolva a definição em 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())

Saída:

[1] "count is 6"

.self é o objeto no qual o método foi chamado. Um método que termina com invisible(.self) retorna o objeto, portanto as chamadas podem ser encadeadas:

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)

Saída:

[1] 9

O método initialize é executado dentro de $new(). initFields(...) define os campos que foram passados; depois, o método pode atribuir valores padrão aos demais. Os métodos chamam uns aos outros pelo nome:

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)

Saída:

[1] 20

Dentro de um método, um <- simples para um nome de campo cria uma variável local com esse nome e deixa o campo inalterado. Use <<- para toda alteração de um 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)

Saída:

[1] 1
challenge icon

Desafio

Fácil

Complete a Classe de Referência Stack em Stack.R. Ela mantém seus itens no campo items (caracteres, com o topo por último) e possui quatro métodos:

  • push(x) adiciona x ao topo e retorna invisible(.self), para que as operações de inserção possam ser encadeadas;
  • pop() remove e retorna o item do topo, ou retorna nothing quando a pilha está vazia;
  • peek() retorna o item do topo sem removê-lo, ou nothing;
  • size() retorna o número de itens.

A definição já está envolvida em suppressMessages(). O código fornecido lê os comandos push a b, pop e peek, depois adiciona mais dois itens em uma única chamada encadeada e imprime o tamanho.

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

Experimente você mesmo

source("Stack.R")

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