by TVSET (Chaplain)
 on Jun 02, 2004 at 09:30 UTC Need Help??

I have been working on a rather complex system recently, which lead me to talking to a lot of my collegues. Here is a piece that I got from those talks. :)

Problem: generate and display a complex interface/menu, which varies from user to user and depends on a number of options. There are plenty of conditions to check and there are multiple combinations of conditions that can produce the same result. The number of conditions and their combinations can grow and change over time. Heh, even describing this is complex. :)

Example:

```if (\$not_in_shift) {
if (\$current || !\$past) {
print "Register for shift\n";
}
}
else {
if (\$current) {
print "Confirm in shift\n";
print "Remove from shift\n";
}
if (\$past) {
print "Confirm in shift\n";
}
}

Even as it is, it already looks ugly. Adding few more conditions and combinations brings code to a real mess and makes it unmaintainable.

Solution: first the code, then explanation.

```#!/usr/bin/perl -w
use strict;

# These can be filled by some function
my %conditions = (
Current => 1,
Not_in_shift => 1,
Past => 0,
);

# Menu item to print if any set of conditions satisfies
(
"Current,Not_in_shift",
"!Past,Not_in_shift",
],
);

# No need to touch this stuff ever
for my \$item ( keys %menu ) {
for my \$set ( @{\$menu{\$item}} ) {
my \$result = 1;
for my \$condition ( split(/,/,\$set) ) {
# Negating condition is a convenient thing to have
if (substr(\$condition,0,1) eq '!') {
substr(\$condition,0,1,'');
(\$result &&= !\$conditions{\$condition}) || last;
}
else {
(\$result &&= \$conditions{\$condition}) || last;
}
}
if (\$result) {
last;
}
}
}

# Whatever we want to do with the menu item
my \$item = shift;
print "\$item !!!\n";
}

Basically, here we have a %conditions hash that contains the current status. It can be updated by a separate function. %menu contains all menu items that can be displayed. For each item, there is a list of combinations (strings). Each combination lists conditions that must true (or false, with negation) to satisfy. Any combination that satisfies all conditions causes the menu item to appear.

The good side of this solution is that it is obvious under which conditions which menu item will get displayed. It is easy to add more items, edit or delete existing ones, or temporarily hide menu items. Chances of making a mistake are lower and it is also possible to store the whole thing outside the code (like in the database or config file) and provide GUI menu editing functionlity. The possibilities are endless. :)
RFC: Tutorial on Testing

Create A New User
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (5)
As of 2017-08-22 15:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
Who is your favorite scientist and why?

Results (337 votes). Check out past polls.

Notices?