Menu
Coddy logo textTech

Setters personalizados

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

Un setter es un método cuyo nombre termina en =. Escribirlo tú mismo en lugar de usar attr_writer permite limpiar el valor antes de almacenarlo:

class Person
  attr_reader :name

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

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

Salida:

[Ada]

Un setter también puede rechazar un valor generando un error. La variable de instancia solo se asigna cuando el valor supera la comprobación, por lo que el objeto conserva su 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

Salida:

price must be positive, got -5
10

Una expresión de asignación siempre devuelve el valor de su lado derecho, no lo que devuelve o almacena el setter. Lee el atributo de nuevo para ver el valor almacenado:

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

Salida:

21.7
22

Un lector y un setter personalizado juntos proporcionan un atributo que el código externo puede leer y cambiar, pero solo a valores válidos. Mantén la comprobación únicamente en el setter, para que cada cambio pase por la misma regla:

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

Desafío

Fácil

Completa la clase Person. Su setter name= elimina los espacios alrededor del valor y escribe en mayúscula cada palabra ( ada lovelace se convierte en Ada Lovelace). Su setter age= genera ArgumentError con el mensaje invalid age: 200 cuando la edad está fuera del rango de 0 a 150 y, de lo contrario, la almacena. Ambos valores se pueden leer.

Un nuevo Person comienza con el nombre Unknown y la edad 0. El código proporcionado lee comandos name text o age n, los aplica mediante los setters e imprime la persona como Ada Lovelace (36) después de cada comando, o muestra el mensaje de error cuando un setter rechaza el valor.

Tu código debe estar en person.rb. main.rb contiene el código proporcionado de entrada/salida y no se puede editar.

Pruébalo tú mismo

require_relative 'person'

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