Menu
Coddy logo textTech

Setters Personalizados

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

Um setter é um método cujo nome termina em =. Escrevê-lo você mesmo em vez de usar attr_writer permite limpar o valor antes de armazená-lo:

class Person
  attr_reader :name

  def name=(value)
    @name = value.strip.capitalize
  end
end

ada = Person.new
ada.name = "   aDA  "
puts "[#{ada.name}]"

Saída:

[Ada]

Um setter também pode recusar um valor gerando um erro. A variável de instância só é atribuída quando o valor passa pela verificação, portanto o objeto mantém seu estado anterior:

class Product
  attr_reader :price

  def initialize(price)
    @price = price
  end

  def price=(value)
    raise ArgumentError, "price must be positive, got #{value}" if value <= 0

    @price = value
  end
end

item = Product.new(10)
begin
  item.price = -5
rescue ArgumentError => e
  puts e.message
end
puts item.price

Saída:

price must be positive, got -5
10

Uma expressão de atribuição sempre retorna o valor do lado direito, não o que o setter retorna ou armazena. Leia o atributo novamente para ver o valor armazenado:

class Thermometer
  attr_reader :celsius

  def celsius=(value)
    @celsius = value.round
  end
end

t = Thermometer.new
result = (t.celsius = 21.7)
puts result
puts t.celsius

Saída:

21.7
22

Um leitor e um setter personalizado juntos fornecem um atributo que o código externo pode ler e alterar, mas apenas para valores válidos. Mantenha a verificação apenas no setter, para que toda alteração passe pela mesma regra:

class Volume
  attr_reader :level

  def level=(value)
    raise ArgumentError, "level must be 0-10" unless (0..10).cover?(value)

    @level = value
  end
end
challenge icon

Desafio

Fácil

Complete a classe Person. Seu setter name= remove os espaços ao redor do valor e coloca cada palavra em maiúscula ( ada lovelace se torna Ada Lovelace). Seu setter age= gera ArgumentError com a mensagem invalid age: 200 quando a idade está fora do intervalo de 0 a 150 e, caso contrário, armazena o valor. Ambos os valores podem ser lidos.

Uma nova instância de Person começa com o nome Unknown e a idade 0. O código fornecido lê os comandos name text ou age n, aplica-os por meio dos setters e imprime a pessoa como Ada Lovelace (36) após cada comando ou exibe a mensagem de erro quando um setter recusa o valor.

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

Experimente você mesmo

require_relative 'person'

# Código de entrada/saída fornecido: mantenha-o como está
input = []
while (line = gets)
  input << line.chomp
end
person = Person.new
input.each do |line|
  command, value = line.split(" ", 2)
  begin
    command == "name" ? person.name = value : person.age = value.to_i
    puts "#{person.name} (#{person.age})"
  rescue ArgumentError => e
    puts e.message
  end
end
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