Menu
CoddyTech

Validation avec les méthodes setter

Fait partie de la section Programmation orientée objet du Journey GDScript de Coddy. Leçon 27 sur 65.

Un setter s’exécute chaque fois que sa propriété reçoit une valeur, ce qui en fait l’endroit où vérifier la nouvelle valeur. Python déclenche une erreur en cas de valeur incorrecte. GDScript n’a pas d’exceptions, donc un setter fait plutôt l’une de ces choses : il borne la valeur à l’intervalle autorisé, ou il conserve l’ancienne valeur et consigne ce qui s’est mal passé.

# character.gd
class_name Character
extends RefCounted

var last_error: String = ""
var hp: int = 100:
	set(value):
		hp = clampi(value, 0, 100)
var nickname: String = "Player":
	set(value):
		if value.length() < 3:
			last_error = "Name too short"
			return
		last_error = ""
		nickname = value

clampi(value, 0, 100) renvoie value ramenée dans l’intervalle de 0 à 100. Dans le setter de nickname, return quitte avant l’affectation, donc l’ancien nom est conservé et last_error explique pourquoi :

# main.gd
var hero := Character.new()
hero.hp = 250
print(hero.hp) # 100
hero.nickname = "Al"
print(hero.nickname) # Joueur
print(hero.last_error) # Nom trop court
hero.nickname = "Alice"
print(hero.nickname) # Alice

Le setter s'exécute également pour les affectations à l'intérieur de la classe, dans _init() et dans chaque méthode. Affectez les arguments du constructeur via la propriété : ils sont alors vérifiés eux aussi :

func _init(start_hp: int) -> void:
	hp = start_hp # appelle le setter : Character.new(500) commence avec 100

Dans le setter lui-même, affecter hp stocke la valeur sans rappeler le setter. La seule affectation qui contourne le setter est la valeur initiale dans la déclaration (= 100) : cette valeur doit donc être valide à elle seule.

challenge icon

Défi

Facile

Ajoutez la validation à la classe Thermostat dans thermostat.gd avec des accesseurs de modification :

  • target (initialisé à 20) n’accepte que les valeurs de 10 à 30. Pour toute autre valeur, il conserve l’ancienne cible et définit last_error sur Target must be between 10 and 30.
  • mode (initialisé à off) n’accepte que heat, cool et off. Pour tout autre texte, il conserve l’ancien mode et définit last_error sur Unknown mode: suivi du texte.
  • Une affectation valide rétablit last_error à une chaîne vide.
  • _init(start_target) affecte start_target à target, afin que l’accesseur de modification vérifie cette valeur.

Le code fourni lit la cible initiale, puis le nombre de commandes, puis une commande par ligne (target 25 ou mode cool). Après la création du thermostat et après chaque commande, il affiche Rejected: suivi de l’erreur lorsque last_error n’est pas vide, puis l’état. Pour la valeur initiale 22 et les commandes target 35 et mode cool, il affiche :

Target 22, mode off
Rejected: Target must be between 10 and 30
Target 22, mode off
Target 22, mode cool

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

Essayez vous-même

extends Node

func _ready():
	# Code d’entrée/sortie fourni : conservez-le tel quel
	var thermostat := Thermostat.new(int(OS.read_string_from_stdin()))
	report(thermostat)
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ")
		if parts[0] == "target":
			thermostat.target = int(parts[1])
		else:
			thermostat.mode = parts[1]
		report(thermostat)

func report(thermostat: Thermostat) -> void:
	if thermostat.last_error != "":
		print("Rejected: " + thermostat.last_error)
	print("Target %d, mode %s" % [thermostat.target, thermostat.mode])
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 GDScript en ligne