Exercise: A Free-Form Memo Pad

Previous Table of Contents Next

Exercise: A Free-Form Memo Pad

Now that you have an easy way to keep data on the disk, it's time to put it to good use. This exercise presents a free-form memo pad that keeps information based on keys and allows you to search and retrieve that information with simple queries.

A sample session with the program (called memopad) is shown in Listing 15.1.

To query the memopad program, simply type the name of a topic, followed by a question mark. To program in a new fact, type a phrase in the form "X is Y", where X is the topic and Y is the information to associate with that topic. You can search the database for similarities by typing "like pattern?" where pattern is a regular expression to search for in the topics. All topics matching that expression will be printed. To exit the program, type quit at the prompt.

Listing 15.1. Sample Session with memopad

Your question: perl?

I don't know about "perl"

Your question: perl is a programming language

Ok, I'll remember "perl" as "a programming language"

Your question: perl's homepage is at

Ok, I'll remember "perl's homepage" as "at"

Your question: perl?

perl is a programming language

Your question: like perl?

perl is like perl

perl's homepage is like perl

Your question: quit

All the information given to the memopad program will be remembered each time the program is run, because the data is stored in a hash tied to a DBM file. The code for memopad is shown in Listing 15.2.

Listing 15.2. Full Listing of memopad

1:   #!/usr/bin/perl -w

2:   use strict;


4:   my(%answers, $subject, $info, $pattern);


6:   dbmopen(%answers, "answers", 0666) || die "Cannot open answer DBM: $!";

7:   while(1) {

8:       print "Your question ('quit' to quit): ";

9:       chomp($_=lc(<STDIN>));

10:      last if (/^quit$/);

11:      if (/like\s+(.*)\?/) {

12:          $pattern=$1;

13:          while( ($subject,$info)=each(%answers) ) {

14:              if ($subject=~/$pattern/) {

15:                  print "$subject is like $pattern\n";

16:              }

17:          }

18:      } elsif (/(.*)\?/) {

19:          $subject=$1;

20:          if ($answers{$subject}) {

21:              print "$subject is $answers{$subject}\n";

22:          } else {

23:              print qq{I don't know about "$subject"\n};

24:          }

25:      } elsif (/(.*)\sis\s(.*)/) {

26:          $subject=$1;

27:          $info=$2;

28:          $answers{$subject}=$info;

29:          print qq{Ok, I'll remember "$subject" as "$info"\n};

30:      } else {

31:          print "I'm sorry, I don't understand.\n";

32:      }

33:  }

34:  dbmclose(%answers);

Lines 12: These lines provide the usual start to Perl programs: a #! line with -w, which means that warnings are enabled. Also, a use strict directive keeps you from making silly mistakes.

Line 6: The hash %answers is tied to the DBM file answers with dbmopen. Two files will be created on diskanswers.pag and answers.dir.

Line 7: while(1) executes the loop forever. Somewhere in the loop is a last or exit to get out of the loop.

Line 9: This line looks confusing because several things are happening at once. lc shifts its scalar argument to lowercase. Because <STDIN> is being used in a scalar context, one line of input from STDIN is read in and subsequently shifted to lowercase, and the result is assigned to $_. chomp is used to remove the trailing newline character.

Line 10: If the input line consists of only the word quit, the while loop is exited.

Line 11: If the input line (now in $_) matches the word like and then some text and then a ?, the text is saved in $1 by the parentheses in the pattern match…

Line 12: and the string in the pattern match from line 11 is saved into $pattern.

Lines 1317: The hash %answers is searched key by key for a key that matches the string in $pattern. As each key is found, it is printed.

Line 18: (This line is a continuation of the if started on line 11.) Otherwise, if the input line ends in a question mark, everything up tobut not includingthe question mark is remembered in $1 with parentheses.

Line 19: The pattern in $1 is saved into $subject.

Lines 2024: If the key $subject is in the hash %answers, then the key and the associated data are printed. Otherwise, the program responds with I don't know.

Lines 2527: (This line is a continuation of the if started on line 11.) Otherwise, if the input line is in the form X is Y, the first part (X) is remembered in $subject and the last part in $info.

Line 28: The information in $info is stored in the hash %answers as $subject.

Line 34: The DBM files are disconnected from %answers.

    Previous Table of Contents Next
    © 2000- NIV