Menu
CoddyTech

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 te 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, así 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. Vuelve a leer el atributo 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 siga 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 método setter name= elimina los espacios alrededor del valor y escribe en mayúscula la primera letra de cada palabra ( ada lovelace se convierte en Ada Lovelace). Su método setter age= genera ArgumentError con el mensaje invalid age: 200 cuando la edad está fuera del intervalo de 0 a 150; de lo contrario, la almacena. Ambos valores se pueden leer.

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

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

Pruébalo tú mismo

require_relative 'person'

# Código de entrada/salida proporcionado: mantenlo tal 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 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