Guard pattern

The guard pattern is common in programming. It's an If statement that prevents your program from doing something crazy.

Goats and apples

Suppose Cthulhu wants a program that figures out how to divide a basket of apples between some goats. Each goat gets an equal number of apples. Here's the program:

  • Dim sApples As Single
  • Dim sGoats As Single
  • Dim sApplesPerGoat As Single
  •  
  • sApples = InputBox("How many apples?")
  • sGoats = InputBox("How many goats?")
  • sApplesPerGoat = sApples / sGoats
  • MsgBox sApplesPerGoat & " apples per goat"

OK, it's not a great program, but it will show the point.

We run the program, and it works fine. Except one time, the program crashes, showing:

Error

Argh!

Reflect

What would make the program crash?

(If you were logged in as a student, the lesson would pause here, and you'd be asked to type in a response. If you want to try that out, ask for an account on this site.)
Georgina
Georgina

Well, if the user typed 0 for the number of goats, that would happen.

Right! Here's part of the code:

  • sApplesPerGoat = sApples / sGoats

Dividing by zero isn't a valid operation.

En garde!

We don't want to try to do the division when we are goatless.

We could change the code to this:

  • Dim sApples As Single
  • Dim sGoats As Single
  • Dim sApplesPerGoat As Single
  •  
  • sApples = InputBox("How many apples?")
  • sGoats = InputBox("How many goats?")
  •  
  • ' Guard against goatlessness
  • If sGoats <> 0 Then
  •     sApplesPerGoat = sApples / sGoats
  •     MsgBox sApplesPerGoat & " apples per goat"
  • End If

Remember that <> means not equal to.

That's the guard pattern. An If that prevents the program doing something.

Marcus
Marcus

Shouldn't we tell the user when that happens?

You're right. The way the program works now, if the user enters zero, the program just doesn't do anything. How about this?

  • Dim sApples As Single
  • Dim sGoats As Single
  • Dim sApplesPerGoat As Single
  •  
  • sApples = InputBox("How many apples?")
  • sGoats = InputBox("How many goats?")
  •  
  • ' Guard against goatlessness
  • If sGoats = 0 Then
  •     MsgBox "Goatlessness detected. Nobody gets apples."
  • Else
  •     sApplesPerGoat = sApples / sGoats
  •     MsgBox sApplesPerGoat & " apples per goat"
  • End If
Marcus
Marcus

Yo, dude! That's what I'm talkin' about.

The guard pattern is very general. It has a lot of uses. Soon, we'll make more specific versions for data validation.

Pattern

Guard pattern

Prevent your code from doing something crazy.