Help:TT Looping Control Structures
HELP PAGE DISCUSSION CLOSE
Revision as of 23:21, 24 March 2013 by Matt (talk | contribs) (1 revision)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

The WHILE control structure

Looping control structures are very useful for generating text that repeat and also printing out contents of arrays and hashes. Here is an example of a code that prints the numbers 1 through 20.

[% count = 1; WHILE count <= 20; count _ "\n"; count = count + 1; END; %]

The example above will result in the output below:

1 2 . . . 19 20

The block of code between the WHILE term and the END term will continue to be executed as long as the conditional statement following the WHILE term remains true. So in our example, the loop continues to run as long as the variable count remains less than or equal to 20. During each iteration of the loop, the variable count is printed, followed by an increment of the variable count by 1. If the iterations (number of loops) of a WHILE control structure exceeds 1000, TT will automatically terminate it to prevent an infinite loop. Here is what a generic WHILE loop may look like.

WHILE condition; ...block of code while condition is true... END;


The FOREACH control structure

The next looping control structure we will be covering is the FOREACH control structure. This control structure is particularly useful for traversing the cells in an array, and the key/value pairs of a hash. Let's create an an array and then use the FOREACH to traverse through it.

[% tray = ['mashed potatoes', 'carrots', 'steak']; count = 1; FOREACH item IN tray; "Tray space ${count} contains ${item}.\n"; count = count + 1; END; %]

The example above will result in the output below:

Tray space 1 contains mashed potatoes. Tray space 2 contains carrots. Tray space 3 contains steak.

We start out by creating an array called tray with three items. Then we also create a variable named count to keep track of each item number as we go through each cell. Now that the array has been created, we begin the traversing of the variable tray with the FOREACH control structure. During each loop, FOREACH grabs the next available cell in tray and then stores it into the variable item. So during the first loop, the variable item holds the value 'mashed potatoes'. Followed by the item number and the item content being printed. Before moving on the the next iteration of the loop, the variable count gets incremented by 1. The loops will continue until all the cells of the variable tray are traversed. Now moving on to a hash traversal.

[% recipe = { 'flour' => '1 cup', 'water' => '1/2 cup', 'yeast' => '1 teaspoon' }; FOREACH ingredient IN recipe.keys; "Add ${recipe.$ingredient} of ${ingredient}.\n"; END; %]

The example above will result in the output below:

Add 1 cup of flour. Add 1 teaspoon of yeast. Add 1/2 cup of water.

After the creation of the hash recipe, the FOREACH control structure loops through the keys of the hash. recipe.keys returns an array of only the keys of recipe. In another words, recipe.keys returns ['flour', 'water', 'yeast']. The variable ingredient is set to the keys of recipe. So for the first loop, the variable ingredient is set to flour. In the output string, ${recipe.$ingredient} returns '1 cup' because ${recipe.$ingredient} is the same as ${recipe.flour}. You can also perform the same hash loop the following way.

[% recipe = { 'flour' => '1 cup', 'water' => '1/2 cup', 'yeast' => '1 teaspoon' }; FOREACH ingredient IN recipe; "Add ${ingredient.value} of ${ingredient.key}.\n"; END; %]

The example above will result in the output below:

Add 1 cup of flour. Add 1 teaspoon of yeast. Add 1/2 cup of water.

The code above essentially does the same thing as before except in a slightly different manner. The FOREACH control structure traverses each hash key and value pair instead of only the keys. The value and key functions are available for each key/value pair (in our case ingredient). So during the first loop, ingredient contains 'flour' => '1 cup', and ingredient.key would return flour while ingredient.value would return '1 cup'.


In FOREACH loops, sometimes you may want to break out of the loop or skip certain loops depending on some condition you set. With the NEXT term you can skip loops. Let's take a look.

[% sweets = { 'chocolates' => 5, 'caramels' => -3, 'cookies' => 2 }; FOREACH item IN sweets; NEXT IF item.value < 0; "There are ${item.value} ${item.key}.\n"; END; %]

The example above will result in the output below:

There are 5 chocolates. There are 2 cookies.

If you look at the first line in the FOREACH loop, you will notice that there is a NEXT statement followed by a IF condition. This line will cause TT move onto the next iteration of the loop if item.value < 0 is true. The 'caramels' entry was not printed in the example above because during the 'caramels' loop, item.value is -3, and since -3 is less than 0, the FOREACH loop skips over to the next iteration.


Now we will be looking into the LAST term. This is used in the same fashion as NEXT except that instead of skipping to the next iteration, LAST breaks completely out of the loop.

[% sweets = { 'chocolates' => 5, 'caramels' => -3, 'cookies' => 2 }; FOREACH item IN sweets; LAST IF item.value < 0; "There are ${item.value} ${item.key}.\n"; END; %]

The example above will result in the output below:

There are 5 chocolates.

Notice that the results are different. This time only the 'chocolates' key/value pair was displayed. This is because when the FOREACH loop was iterating through the 'caramels' key/value pair, the condition item.value < 0 became true and so the loop terminated completely, jumping past the END term. For more detailed information regarding looping control structures, Click Here.


Back to Table of Contents