Perl - Giving Each Person a Different Secret Word

If I want the secret word to be different for each person who is given access to the program, then I figure some kind of "table" would be needed to match up the people with their word.

Person Secret Word
Jason camel
Michele llama
Tracey alpaca
Karee pea
Patrick alpaca

Notice that both Tracey and Patrick have the same secret word.  This is OK for this application but in real life (e. g., a "password" table) you'd want them all to be different.

It turns out that the easiest way to store such a table in Perl is with a hash.  Each element of the hash holds a separate scalar value (just like an array), but the hashes are referenced by a key, which can be any scalar value (any string or number, including non-integer and negative values).  So, to create a hash called %words (notice the % rather than @) with the keys and values given in the table above, we assign a value to %words (much as we did earlier with the array):

	%words = qw(
		Jason	camel
		Michele	llama
		Tracey	alpaca
		Karee	pea
		Patrick	alpaca
	);

Each pair of values in the list represents one key and its corresponding value in the hash.  Note that we broke this assignment over many lines without any sort of line-continuation character, because whitespace is generally insignficant in a Perl program.

To find the secret word for Jason, we need to use Jason as the key in a reference to the hash %words, via some expression such as $words{"Jason"}.  The value of this reference is camel, similar to what we had before with the other array.  Also as before, the key can be an expression, so setting $person to Jason and evaluating $words{$person} gives camel as well.

Putting this all together, we get a program like this:

#!/usr/bin/perl -w
%words = qw(
	Jason	camel
	Michele	llama
	Tracey	alpaca
	Karee	pea
	Patrick	alpaca
);
print "What is your name? ";
$name = <STDIN>;
chomp ($name);
if ($name eq "Larry") {
	print "Hello, Larry!  How good of you to be here!\n";
}
else {
	print "Hello, $name!\n"; 			# ordinary greeting
	$secretword = $words{$name};			# get the secret word
	print "What is the secret word? ";
	$guess = <STDIN>;
	chomp ($guess);
	while ($guess ne $secretword) {
		print "Wrong, try again.  What is the secret word? ";
		$guess = <STDIN>;
		chomp ($guess);
	}						# end of while not correct
	print "Good guess!  Have a great day!!";
}

Note the lookup of the secret word.  If the name is not found, the value of $secretword will be an empty string (well, actually it's the undef value, but it looks like an empty string to the eq operator), which we can then check for if we want to define a default secret word for everyone else.  Here's how that would look:

	[ . . . previous part of program not shown . . . ]
		$secretword = $words{$name};		# get the secret word
		if ($secretword eq "") {		# oops, not found
			$secretword = "mfd";		# now there's a secret word
		}
		print "What is the secret word? ";
	{ . . . balance of program not shown . . . ]

Now, if I enter Larry Boatman or larry rather than Larry, I'm lumped in with the rest of the users of the program, because the eq comparison is an exact equality.  What programming elements do you suppose are required to accomplish the task of permitting a match on part of a response and even if the response is in all upper, all lower, or a mix of upper and lower cases?  See you next lesson!