Managing Rich Data Structures

Managing Rich Data Structures
by Dave Baker |

Next, the script determines which of the three data types it has found, based on its name (of course, your system might work a little differently). Once it knows it has a file containing a target URL, for example, it opens the file, extracts the URL, trims surrounding white space from it, and then does the "get, change, set" procedure necessary to store a part of hash using MLDBM. Notice the use of a temporary variable to hold the value of the key for the date of the URL file being processed.

my $entry = $data_for_ad_on{$1};                   # Get

"There might be no existing value to put into $entry!" you say (as would occur if this is the first data file associated with the date). You're right, but it's part of "get, change, set." Watch this next step:

$entry->{url} = $url;                              # Change

Because $entry looks like a hash reference, Perl makes it into one! The value of the target URL from the text file gets stored as the value of a key in an anonymous hash; $entry contains the reference (memory location) of the hash.

Finally, the program sets the value into the mother hash, assigning the reference to the hash; the hash now contains a newly stoked URL key/value pair:

$data_for_ad_on{$1} = $entry;

Note that the date (stored in $1) will be the same for each of three different pieces of data. At first glance, it might seem that this would overwrite existing data by having this assignment statement appear as the "set" phase for each of the three pieces of data. There is no conflict in storing the same hash reference as the value for that date, however. The first of those three to be assigned a key/value (the URL, for example) will give the hash its initial content: a hash having one key/value pair. Storing another key pair (the .gif, for example) changes the hash to contain two key/value pairs with unique keys (url, gif). Finally the hash receives a third key/value pair, but the memory location of the hash--its reference--stays the same.

Reading HoH Data

How do I access the data stored in the DBM database file? It turns out to be almost simple, requiring just a little references-related syntax.

Reach into the %ad_data hash by naming a key ($data_for_ad_on{$date} where $data has a specific value assigned). Then, because the associated value for that key is not a simple scalar but instead is a hash reference, use the appropriate arrow infix notation to dereference the values of the desired keys in that referenced hash (url, gif, or headline).

Lines 0 through 7 are the same as in the previous examples. The meat is:

=8=   my @dates = sort keys %data_for_ad_on;

=9=   my ($url, $gif, $headline);

=10=  for my $date (@dates) {



=11=      $url      = $data_for_ad_on{$date}->{url} || 'None in database';



=12=      $gif      = $data_for_ad_on{$date}->{gif} || 'None in database';



=13=      $headline = $data_for_ad_on{$date}->{headline}

    || 'None in database';



=14=      print "\nOn $date, we'll run the banner:\n";

=15=      print "      Target URL of banner: $url\n";

=16=      print "        Location of banner: $gif\n";

=17=      print "     Headline above banner: $headline\n";

=18=  }

Updating HoH Data

The final task is to update data in the database. Here I encountered a small wrinkle, explained at page 559 of Perl Cookbook, 2nd Edition. A limitation of Perl's tie function is that you cannot modify a piece (or add a piece) of an MLDBM value directly.

$data_for_ad_on{'2005_12_09'}->{url}

    = 'http://roadrunners-r-us.com/newpage.html';   # WRONG

Instead, the procedure is "get, change, set" the piece of the stored structure you're modifying, using a temporary variable (here called $entry).

my $entry = $data_for_ad_on{'2005_12_09'};                  # Get

$entry->{url} = 'http://roadrunners-r-us.com/newpage.html'; # Change

$data_for_ad_on{'2005_12_09'} = $entry;                     # Set

I simply assigned a value to the entire hash in my first example (creation of the tied database file), because I wasn't working with a piece of the tied hash--I was creating the entire tied hash.

Similarly, adding an entire key/value pair to the hash doesn't involve a temporary variable. Here's how to add data for a banner for another date. Lines 0 through 7 are still the same. Then:

=8=  ad_data_for{'2005_12_11'}  = {

         url          => 'http://newadvertiser.com/',

         gif          => 'http://benefitslink.com/banners/newadvertiser.gif',

         headline     => 'Shop Benefits Mart for all your benefit needs!',

                                  };

Upon exiting the script, the new 2005_12_11 key and the associated value (the anonymous hash reference) will be in the %ad_data_for hash.

How can you add a piece? That would require the use of a temporary variable. Suppose I want to add a new key/value pair as part of the data for a particular existing banner. Here's how I might add paid_status to the banner ad for December 10, 2005:

Lines 0 through 7 are still the same. Then:

    # Get (a hash reference)

=8=  my $entry              = $data_for_ad_on{'2005_12_10'};

     # Change (via autovivification of a new key/value)

=9=  $entry->{paid_status}  = 0;

    # Set (the changed hash reference into the tied hash)

=10= $data_for_ad_on{'2005_12_10'} = $entry;

To see the results of adding such a new piece, keep lines 0 through 7 unchanged. Then:

=8=   my @dates = sort keys %data_for_ad_on;

=9=   my ($url, $gif, $headline);

=10=  for my $date (@dates) {



=11=      $url      = $data_for_ad_on{$date}->{url} || 'None in database';



=12=      $gif      = $data_for_ad_on{$date}->{gif} || 'None in database';



=13=      $headline = $data_for_ad_on{$date}->{headline}

    || 'None in database';



=14=      $paid_status = defined $data_for_ad_on{$date}->{paid_status}

              # If defined, show value (e.g., 0 or 1)

              ? $data_for_ad_on{$date}->{paid_status}

              # If undefined, show that fact

              : 'Not defined for this banner';



=15=      print "\nOn $date, we'll be running this banner:\n";

=16=      print "      Target URL of banner: $url\n";

=17=      print "        Location of banner: $gif\n";

=18=      print "     Headline above banner: $headline\n";

=19=      print "      Paid status (0 or 1): $paid_status\n";

=20=  }

Conclusion

I hope this article helps you move from a swamp of weedy text files into the simplicity of a single database file. Please let me know if you have any comments, including criticisms or suggestions for improvement!

Prev  [1] [2] [3] 

Close    To Top
  • Prev Article-Programming:
  • Next Article-Programming:
  • Now: Tutorial for Web and Software Design > Programming > Perl > Programming Content
    Photoshop Tutorial
     

    Special Effect

      3D Effect
      Photoshop Articles
    Programming Tutorial
     

    C/C++ Tutorial

      Visual Basic
      C# Tutorial
    Database Tutorial
     

    MySQL Tutorial

      MS SQL Tutorial
      Oracle Tutorial
    Geek Tutorial
     

    Blogging Tutorial

      RSS Tutorial
      Podcasting Tutorial
    Graphic Design Tutorial
      Coreldraw Tutorial
      Illustrator Tutorial
      3D Tutorials
    Webmaster Articles
     

    Domain Service

      Web Hosting
      Site Promotion
    Java Tutorial/ Articles
     

    Java Servlets

      JavaEE Tutorial
     

    JavaBeans Tutorial

    XML Tutorial/ Articles
     

    XML Style

      AJAX Tutorial
      XML Mobile
    Flash Tutorial/ Articles
     

    Flash Video

      Action Script
      Flash Articles
    OS Tutorial/ Articles
      Linux Tutorial
      Symbian Tutorial
      MacOS Tutorial
    Personal Tech
      Hardware Tutorial
      Software Tutorial
      Online Auction