in reply to Hashes/ Simple Database

You haven't told us how it's supposed to be writing it out to file. One way to do it would be to build your data structure then output it to file with Data::Dumper and then recreate the struture in you file with require 'file'. This is a simple way of storing data from a hash. Alternativly have a look at a database such as DBD::CSV which is a backend for DBI allowing you to use a plain text file like a full database.

For the code you are showing you may want to eithier display a list of books ie. print(join "\n",keys %borrowed_DB) or use inexact matching, maybe grepping the keys for a book title that contains the specifed text.

Replies are listed 'Best First'.
Re: Re: Hashes/ Simple Database
by bmhm (Beadle) on Dec 04, 2000 at 12:35 UTC
    I am not using any module for this program. I wanted to be able to hand code the entire thing. The written out file looks like this Author's Name:Book:Book:Book/Borrower:Book Where the colon separates the Books and author and the slash separates the particular book from the borrowee.

      Well, if you're saving the database as a flat file, you'll want to chomp $borrower before you use it in an assignment, otherwise you're file will look like:

           Author's Name:Book/Borrower
           :Book:Book:Book 
      

      rather than

           Author's Name:Book/Borrower:Book:Book:Book 
      

      This would also explain why it looks like the author's other books seem to have been erased.

      How are you building your hash?
      If I was doing this I might use a hash of hashes such as:
      $book{author}{book_name} = $borrower; which you could output all in one swoop with
      for my $author (keys %book) { print FILE $author; while (my ($book,$borrow) = each %{$book{$author}}) { print FILE ':' . $book; print FILE '/' . $borrow if $borrow; } print FILE "\n"; }
      The input is of course comparable.
      If you are using (as you seem to be) keys which are the author's name joined to the book title I would say you are making trouble for yourself and making the output code harder than it should be.

      Note: since this is homework I probably should not have given you that code, but well I did anyway....

      I think what is meant is that the standard approach is to have your own "hand-coded" module of subroutines for your system, which, in particular, should have two subroutines, say getF and putF, which handle the writing to a file, for example:

      sub getF { # warning: untested "dreamware" ... I'll test later and # (if necessary) repost a correction # General routine to read any file into a hash # (key-indexed) whose targets are anonymous hashes # (indexed by your column names) my ( $hashAdr, # reference of hash to write back to - this on +e $fileHandle, # best not to hard-code these around the place # but to have one subroutine per system # that allocates unique ones, which would # therefore get called in the main program $fileName, $fieldDelim, # best use only one per PROJECT # and if in doubt use "$;" $colNamArrAdr, # address of array of the column names - # best to use all upper or all lower case # if possible. $indexPosn # can be e.g. "3" . $; . "4" to say # that the index should be composed of columns # 4 and 5 (surpri-ise!). ) = @_; %$hashAdr = (); # initialise the hash while( <$fileHandle> ) { chop; # you know exactly one <CR> is there. my @cols = split( $fieldDelim, $_ ); my $index = join( "", split( $;, $cols[ $indexPosn ] ) ); # above is designed to handle 1 or more index columns foreach ( @$colNamArrAdr ) { $$hashadr{ $index }{ $_ } = shift( @cols ); } } return; } # the corresponding put routine is obvious from this, but # I'll just mention the important loop: foreach my $key ( sort( keys( %$hashAdr ) ) ) { my @output = (); foreach ( @$colNamArrAdr ) { push( @output, $$hashAdr{ $key }{ $_ } ); } print $fileHandle join( $fileDelim, @output ), "\n"; }