Menu
CoddyTech

Setters personnalisés

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

Un accesseur en écriture 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}]"

Résultat :

[Ada]

Un setter peut également refuser une valeur en levant une erreur. La variable d’instance n’est assignée que lorsque la valeur satisfait 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

Résultat :

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. Relis 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 accesseur personnalisé en écriture permettent au code externe de lire et de modifier un attribut, mais uniquement avec des valeurs valides. Gardez la vérification uniquement dans l’accesseur en écriture, afin que chaque modification soit soumise à 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 en écriture name= supprime les espaces autour de la valeur et met une majuscule au début de chaque mot ( ada lovelace devient Ada Lovelace). Son accesseur en écriture age= lève ArgumentError avec le message invalid age: 200 lorsque l’âge est en dehors de l’intervalle de 0 à 150, et l’enregistre 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 à l’aide des accesseurs en écriture et affiche la personne sous la forme Ada Lovelace (36) après chaque commande, ou le message d’erreur lorsqu’un accesseur en écriture 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 : conservez-le 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