Menu
Coddy logo textTech

Variáveis de Instância da Classe

Parte da seção Programação orientada a objetos do Journey de Ruby da Coddy. Lição 13 de 57.

Uma classe também é um objeto, portanto pode ter suas próprias variáveis de instância. @issued = 0 no corpo da classe, onde self é a classe, pertence à classe e não a nenhuma instância. Os métodos de classe leem e alteram esse valor:

class Ticket
  @issued = 0

  def self.issue
    @issued += 1
  end

  def self.issued
    @issued
  end
end

Ticket.issue
Ticket.issue
puts Ticket.issued

Saída:

2

attr_accessor dentro de class << self gera um leitor e um definidor na classe. As instâncias então acessam o estado da classe por meio de self.class, por exemplo, para contar cada objeto que new cria:

class Robot
  @built = 0

  class << self
    attr_accessor :built
  end

  attr_reader :serial

  def initialize
    self.class.built += 1
    @serial = self.class.built
  end
end

a = Robot.new
b = Robot.new
puts "#{a.serial} #{b.serial} #{Robot.built}"

Saída:

1 2 2

Ruby também tem variáveis de classe, escritas como @@name. Uma variável de classe é compartilhada pela classe e por todas as suas instâncias, portanto os métodos de instância podem lê-la diretamente:

class Player
  @@count = 0

  def initialize
    @@count += 1
  end

  def self.count
    @@count
  end

  def others
    @@count - 1
  end
end

Player.new
last = Player.new
puts Player.count
puts last.others

Saída:

2
1

Uma variável de classe também é compartilhada com cada subclasse (uma classe construída com base em outra, capítulo 5), portanto, uma subclasse que atribui um valor a ela também o altera para a classe-pai. Uma variável de instância de classe permanece separada por classe, e é por isso que a maior parte do código Ruby prefere usá-la:

class Base
  @@kind = "base"
  @label = "base"

  class << self
    attr_reader :label
  end

  def self.kind
    @@kind
  end
end

class Child < Base
  @@kind = "child"
  @label = "child"
end

puts Base.kind
puts Base.label
puts Child.label

Saída:

child
base
child
challenge icon

Desafio

Fácil

Complete a classe Ticket. Cada novo ticket recebe o próximo número, começando em 1, a partir de um contador mantido em uma variável de instância da classe. Ticket.issued retorna quantos tickets foram emitidos desde o último reset, e Ticket.reset define o contador novamente como 0. to_s retorna #3 Concert.

O código fornecido lê linhas. reset redefine o contador; qualquer outra linha é um nome de evento, para o qual ele cria um ticket e o imprime. No final, ele imprime issued: 2.

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

Experimente você mesmo

require_relative 'ticket'

# Código de entrada/saída fornecido: mantenha-o como está
input = []
while (line = gets)
  input << line.chomp
end
input.each do |line|
  if line == "reset"
    Ticket.reset
  else
    puts Ticket.new(line)
  end
end
puts "issued: #{Ticket.issued}"
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 Ruby online