Menu
CoddyTech

Validação com setters

Parte da seção Programação orientada a objetos do Journey de GDScript da Coddy. Lição 27 de 65.

Um setter é executado toda vez que sua propriedade recebe um valor, o que faz dele o lugar certo para verificar o novo valor. Python gera um erro para um valor inválido. GDScript não tem exceções, então um setter faz uma destas coisas: limita o valor ao intervalo permitido ou mantém o valor antigo e registra o que deu errado.

# 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) retorna value ajustado ao intervalo de 0 a 100. No setter de nickname, return interrompe a execução antes da atribuição, então o nome antigo permanece e last_error explica o motivo:

# main.gd
var hero := Character.new()
hero.hp = 250
print(hero.hp) # 100
hero.nickname = "Al"
print(hero.nickname) # Player
print(hero.last_error) # Name too short
hero.nickname = "Alice"
print(hero.nickname) # Alice

O setter também é executado para atribuições dentro da classe, em _init() e em todos os métodos. Atribua os argumentos do construtor por meio da propriedade e eles também serão verificados:

func _init(start_hp: int) -> void:
	hp = start_hp # executa o setter: Character.new(500) começa com 100

Dentro do próprio setter, atribuir hp armazena o valor sem chamar o setter novamente. A única atribuição que não passa pelo setter é o valor inicial na declaração (= 100), então esse valor precisa ser válido por si só.

challenge icon

Desafio

Fácil

Adicione validação à classe Thermostat em thermostat.gd com setters:

  • target (começa em 20) aceita apenas valores de 10 a 30. Para qualquer outro valor, mantém o target antigo e define last_error como Target must be between 10 and 30.
  • mode (começa em off) aceita apenas heat, cool e off. Para qualquer outro texto, mantém o modo antigo e define last_error como Unknown mode: seguido do texto.
  • Uma atribuição válida redefine last_error para uma string vazia.
  • _init(start_target) atribui start_target a target, para que o setter faça a verificação.

O código fornecido lê o target inicial, depois o número de comandos e, em seguida, um comando por linha (target 25 ou mode cool). Depois de criar o termostato e após cada comando, ele imprime Rejected: e o erro quando last_error não está vazio, e então o estado. Para o início 22 e os comandos target 35 e mode cool, ele imprime:

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

Seu código deve ficar em thermostat.gd. main.gd contém o código fornecido de entrada/saída e não pode ser editado.

Experimente você mesmo

extends Node

func _ready():
	# Código de entrada/saída fornecido: mantenha-o como está
	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 iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação orientada a objetos

Pratique por conta própria: Compilador de GDScript online