0%

Protecting Valid Object State · practice

Change Related State Together

A property setter is a good boundary for one assignable . It is the wrong boundary when one real change has several consequences.

Suppose an attempt can be reassigned to a different quiz. Its quiz name and its old results must change together:

attempt.quiz_name = "Chapter 5 Review"
attempt.results = []

Between those lines the lies. It names the new quiz while still holding answers from the old one.

One operation for one change

Reassignment is an event, so give it one :

Try it

Both assignments belong to the method. The supported public interface offers no half-change operation; the leading underscores tell callers that assigning the storage directly would break the object’s rules.

Validate before changing anything

The order inside reassign_to is load-bearing. Check every proposed value before the first . If validation happens between assignments, an can leave the object half old and half new.

Why does reassign_to validate the new name before clearing the results?

The pattern is small: validate everything, then apply everything. Use it when several attributes together describe one state. For a single independently assignable value, the setter from the previous lesson remains the simpler tool.

The exercise makes a rejected revision prove the rule by checking that neither field changed.

Task

Write Question.revise(prompt, answer), replacing the prompt and answer together.

Both values must be non-empty. If either is unacceptable, raise and leave the question completely unchanged. Check both proposed values before assigning either one.

Run the program. The valid revision should replace both fields; the refused revision should leave both previous values intact.