Menu
Coddy logo textTech

Setters personnalisés

Fait partie de la section Programmation orientée objet du Journey Ruby de Coddy. Leçon 8 sur 57.

Un setter est une méthode dont le nom se termine par =. L’écrire vous-même au lieu d’utiliser attr_writer vous permet de nettoyer la valeur avant de la stocker :

class Person
  attr_reader :name

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

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

Sortie :

[Ada]

Un setter peut également refuser une valeur en levant une erreur. La variable d’instance n’est affectée que lorsque la valeur passe la vérification, de sorte que l’objet conserve son ancien état :

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

Sortie :

price must be positive, got -5
10

Une expression d’affectation renvoie toujours la valeur située à sa droite, et non ce que le setter renvoie ou stocke. Relisez l’attribut pour voir la valeur stockée :

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

Sortie :

21.7
22

Un accesseur en lecture et un setter personnalisé fournissent ensemble un attribut que le code externe peut lire et modifier, mais uniquement avec des valeurs valides. Gardez la vérification uniquement dans le setter, afin que chaque modification passe par la même règle :

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

Défi

Facile

Complétez la classe Person. Son accesseur name= supprime les espaces autour de la valeur et met chaque mot en majuscule ( ada lovelace devient Ada Lovelace). Son accesseur age= lève ArgumentError avec le message invalid age: 200 lorsque l’âge est en dehors de l’intervalle de 0 à 150, et le stocke sinon. Les deux valeurs peuvent être lues.

Un nouvel objet Person commence avec le nom Unknown et l’âge 0. Le code fourni lit les commandes name text ou age n, les applique via les accesseurs et affiche la personne sous la forme Ada Lovelace (36) après chaque commande, ou le message d’erreur lorsqu’un accesseur refuse la valeur.

Votre code doit être placé dans person.rb. main.rb contient le code d’entrée/sortie fourni et ne peut pas être modifié.

Essayez vous-même

require_relative 'person'

# Code d'entrée/sortie fourni : le garder tel quel
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 iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation orientée objet

Entraînez-vous par vous-même : Compilateur Ruby en ligne