Perl CGI  «Prev  Next»

Lesson 4 The state-machine example
ObjectiveExamine an Example of the State-Machine Model in Perl

Examine Example of the State-Machine Model in Perl

This is the simplest possible state-machine. It has only two states:
  1. first
  2. validate
When the program is first called, and it has no query string, it is put in the first state. Here's the code that determines the state:
# the main jump table
if    ($state eq 'first'   ) { first()    }
elsif ($state eq 'validate') { validate() }
else                         { unknown()  }

Example of a State Machine Model in Perl 5

Here's an example of a state machine model in Perl 5. I will use a simple traffic light system as an illustrative example. We'll leverage a hash-based approach for clarity:
use strict;
use warnings;

# Define our states
my %states = (
    GREEN  => sub { print "Traffic flows (Green light)\n"; },
    YELLOW => sub { print "Prepare to stop (Yellow light)\n"; },
    RED    => sub { print "Traffic halted (Red light)\n"; },
);

# Initial state
my $current_state = "GREEN";

# Transition logic (simplified for this example)
my %transitions = (
    GREEN  => 'YELLOW',
    YELLOW => 'RED',
    RED    => 'GREEN',
);

# Main loop (you'd likely integrate this with a timer/event system in a real application)
for (1 .. 5) {  # Simulate 5 state changes
    $states{$current_state}->();  # Execute the action for the current state

    $current_state = $transitions{$current_state};  # Transition to the next state
}
Explanation
  1. States: The `%states` hash stores our states ('GREEN', 'YELLOW', 'RED'). Each state is associated with an anonymous subroutine (code block) that defines the action to take when in that state.
  2. Transitions: The `%transitions` hash determines the valid transitions between states.
  3. Main Loop: The loop simulates a simple state machine. In each iteration:
    • It executes the subroutine associated with the `$current_state`.
    • It updates the `$current_state` based on the `%transitions` rules.

Key Points
  • Real-World Complexity: In more intricate state machines, you'd likely handle input events to trigger transitions and introduce logic to determine the next state.
  • Modules: Consider using modules like `FSM::Simple` or `Auto::Mata` for more complex state machine implementations. These provide features like state entry/exit actions and richer transition definitions.

When the first state is detected, the first() function is called. That displays a simple prompt screen (the one that asks if you are having fun). After that screen is displayed, the program must exit. It has to release the server channel after the browser gets the screen.
In the HTML for the first state, this hidden form element is included:
<input type=hidden name=state value=validate>
That tells the state-machine what state to be in when it is called from this form.
When the user presses the Submit button, the program is called again with the state variable set to validate. The validate() routine is called, and then it decides if the user is having fun or not and gives the user the appropriate screen.
Hopefully you can see the power of state-machines from this very simple example. You can also see that if there are more than a couple of states, the program can quickly become large. And with all the HTML embedded in the program, it can become difficult to maintain, especially if you are working with a designer or artistic director.
The solution to those problems is in the next lesson, "Perl-based HTML."