Validación con setters
Parte de la sección Programación orientada a objetos del Journey de GDScript de Coddy. Lección 27 de 65.
Un setter se ejecuta cada vez que se asigna un valor a su propiedad, por lo que es el lugar adecuado para comprobar el nuevo valor. Python genera un error si el valor no es válido. GDScript no tiene excepciones, así que un setter hace una de estas cosas: limita el valor al rango permitido o conserva el valor anterior y registra qué salió mal.
# 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 = valueclampi(value, 0, 100) devuelve value ajustado al rango de 0 a 100. En el setter de nickname, return sale antes de la asignación, así que se conserva el nombre anterior y last_error explica el 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) # Nombre demasiado corto
hero.nickname = "Alice"
print(hero.nickname) # AliceEl setter también se ejecuta para las asignaciones dentro de la clase, en _init() y en todos los métodos. Asigna los argumentos del constructor a través de la propiedad y también se comprobarán:
func _init(start_hp: int) -> void:
hp = start_hp # ejecuta el setter: Character.new(500) empieza con 100Dentro del propio setter, asignar hp almacena el valor sin volver a llamar al setter. La única asignación que omite el setter es el valor inicial en la declaración (= 100), así que ese valor debe ser válido por sí solo.
Desafío
FácilAñade validación a la clase Thermostat en thermostat.gd con setters:
target(empieza en20) solo acepta valores de10a30. Para cualquier otro valor, conserva el objetivo anterior y establecelast_errorenTarget must be between 10 and 30.mode(empieza enoff) solo aceptaheat,coolyoff. Para cualquier otro texto, conserva el modo anterior y establecelast_errorenUnknown mode:seguido del texto.- Una asignación válida restablece
last_errora una cadena vacía. _init(start_target)asignastart_targetatarget, para que el setter lo compruebe.
El código proporcionado lee el objetivo inicial, después el número de comandos y, después, un comando por línea (target 25 o mode cool). Después de crear el termostato y después de cada comando, imprime Rejected: y el error cuando last_error no está vacío, y luego el estado. Para el valor inicial 22 y los comandos target 35 y mode cool, imprime:
Target 22, mode off
Rejected: Target must be between 10 and 30
Target 22, mode off
Target 22, mode coolTu código va en thermostat.gd. main.gd contiene el código proporcionado de entrada/salida y no se puede editar.
Pruébalo tú mismo
extends Node
func _ready():
# Código de entrada/salida proporcionado: mantenlo tal 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])
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
1Fundamentos de la programación orientada a objetos
Archivos externosIntroducción a la programación orientada a objetosClases vs. objetosLa palabra clave selfMétodosPropiedadesConstructor (_init)Repaso: calculadora sencilla4Polimorfismo
Repaso de la sobrescritura de métodosTipado patoClases y métodos abstractosDiseño de interfacesRepaso: calculadora de formas7Señales
¿Qué es una señal?Declarar y emitirConectarse a las señalesSeñales con argumentosRepaso: sistema de salud10Patrones de diseño, parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón Composite2Propiedades de clase
Variables de instancia y estáticasFunciones estáticasMétodos setter de propiedadesMétodos getter de propiedadesPrivado por convenciónRepaso: administrador de cuentas bancarias5Encapsulación
Miembros públicos y privadosValidación con settersOcultación de informaciónPropiedades de solo lecturaRepaso: sistema de registros de estudiantes8Conceptos avanzados de POO
Composición frente a herenciaClases internasNodos como componentesRefCounted frente a NodeEnums en clases3Herencia
Herencia básicaLa palabra clave superSobrescritura de métodosCadenas de herenciaComprobaciones de tipo con isRepaso: jerarquía de empleados6Métodos especiales
Introducción a los métodos virtualesEl método _to_stringIteradores personalizadosRepaso: lista personalizada9Patrones de diseño, parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón StrategyPractica por tu cuenta: Compilador de GDScript online