in reply to Re^5: Some one help me with this code.how to make it work.
in thread Some one help me with this code.how to make it work.
Summary
Here are some extremely simplified examples of the basic techniques which would reliably convert a hash to and from a file under relatively reasonable constraints.
As you requested in private chat, I've avoided the use of modules and deprecated functionality (such as dbmopen).
Please note that this is not product-grade code -- reading and writing individual records from a data file is a much more efficient use of CPU, memory, and other runtime resources than this slurp/process/spew approach.
The Slurp/Spew approach simply makes it easier to demonstrate the underlying techniques.
Design
In this example, the design is simplistic:
Code
So, without further adieu, a working sample, as requested:
hashfile1.pl:
#!/usr/bin/perl use strict; use warnings; my $EmployeeDataFilename = 'emp.dat'; my %EmployeeInfo = (); # -----[ Initialize ]------------------------------------------------- +---------- # We cold have also demonstrated how to code up the population of a ha +sh from # its declarative statement above, but I felt this would make more sen +se to # someone new to Perl: # -------------------------------------------------------------------- +---------- { $EmployeeInfo{'A001'}{'FIRSTNAME'} = 'George'; $EmployeeInfo{'A001'}{'LASTNAME'} = 'Burns'; $EmployeeInfo{'A001'}{'AGE'} = 99; $EmployeeInfo{'A002'}{'FIRSTNAME'} = 'Luke'; $EmployeeInfo{'A002'}{'LASTNAME'} = 'Skywalker'; $EmployeeInfo{'A002'}{'AGE'} = 21; } # -----[ Process ]---------------------------------------------------- +---------- { &readEmployeeFile(); # Modify one of the elements -- pretend it's George's birthday. $EmployeeInfo{'A001'}{'AGE'}++; &writeEmployeeFile(); } exit; sub readEmployeeFile { # --------------------------------------------------------------- +----------- # For the simple version, we will simply load the entire file int +o a hash # each time, then write the whole thing back out each time. # # This is NOT efficient, will NOT scale well, and is generally a +poor design # for a production product. # # It does, however, have the advantage of demonstrating a number +of # necessary techniques for writing a better system without clutte +ring up the # process with record management logic. # --------------------------------------------------------------- +----------- if (!open EMPFIL, '<', $EmployeeDataFilename) { print "Cannot open input file \"$EmployeeDataFilename\"\n"; } else { # File sucessfully opened. Read all employee data and store + in the hash while (my $empbuf = <EMPFIL>) { chomp $empbuf; my ($employeeID, $lastName, $firstName, $age, $garbage) + = split /\t/, $empbuf, 4; my $empkey = uc $employeeID; $EmployeeInfo{$empkey}{'LASTNAME'} = $lastName; $EmployeeInfo{$empkey}{'FIRSTNAME'} = $firstName; $EmployeeInfo{$empkey}{'AGE'} = $age; } close EMPFIL; } } sub writeEmployeeFile { # --------------------------------------------------------------- +----------- # For the simple version, we will simply rewrite the entire file +each time # Doing otherwise requires either use of deprecated functionality +, modules, # or more complex coding techniques which exceed the initial +scope of # this example. # --------------------------------------------------------------- +----------- if (!open EMPFIL, '>', $EmployeeDataFilename) { print "Cannot open output file \"$EmployeeDataFilename\"\n"; } else { # File sucessfully opened. Write each employee data to the +file foreach my $empkey (sort keys %EmployeeInfo) { print "Storing employee ID $empkey\n"; # ----------------------------------------------------- +------------- # First convert the hash data to a tab-separated values + format # NOTE: This requires that the data contains no tabs o +r that a way # to encapsulate tabs is taken into consideratio +n. To keep # this example simple, we will intentionally mak +e the poor # engineering choice of presuming the data to ha +ve no tabs. # ----------------------------------------------------- +------------- my $tsvdat = &makeTsvData( $empkey, $EmployeeInfo{$empkey}{'LASTNAME'}, $EmployeeInfo{$empkey}{'FIRSTNAME'}, $EmployeeInfo{$empkey}{'AGE'} ); # Now converted to a single line of text, write the dat +a to the file print EMPFIL "$tsvdat\n"; } close EMPFIL; } } # -----[ makeTsvData() ]---------------------------------------------- +---------- # This is a largely-useless subroutine, but it could be moulded into s +omething # very useful. Right now it presumes exactly four parameters, knows w +hat they # are supposed to be, and the only service it really provides is conve +rting any # undef values to blank or zero depending on whether it is intended as + string or # numeric. The crux of the routine is the join statement, which could + simply # have been done in the main code, but I wanted to demonstrate the abi +lity to # use a subroutine to perform more complex data validation and manipul +ation # without muddying up your main script. This is kept deliberately sim +ple as it # is meant to be an example to inspire other uses and to demonstrate t +he # technique; in the real world, I would have made this routine much mo +re generic # and much more robust. # -------------------------------------------------------------------- +---------- sub makeTsvData { my ($employeeID, $lastName, $firstName, $age) = @_; # Cleans the input if (!defined $employeeID) { $employeeID = ''; } if (!defined $lastName) { $lastName = ''; } if (!defined $firstName) { $firstName = ''; } if (!defined $age) { $age = 0; } my $tsvData = join "\t", $employeeID, $lastName, $firstName, $age +; return $tsvData; } __END__
And what code would be complete without a way to see what your data is actually doing (and yet avoiding the use of the otherwise most excellent Data::Dumpand Data::Dumpermodules):
hashlist1.pl:
#!/usr/bin/perl use strict; use warnings; my $EmployeeDataFilename = 'emp.dat'; my %EmployeeInfo = (); { if (!open EMPFIL, '<', $EmployeeDataFilename) { print "Cannot open input file \"$EmployeeDataFilename\"\n"; } else { # File sucessfully opened. Read all employee data and store + in the hash while (my $empbuf = <EMPFIL>) { chomp $empbuf; my ($employeeID, $lastName, $firstName, $age, $garbage) + = split /\t/, $empbuf, 4; my $empkey = uc $employeeID; $EmployeeInfo{$empkey}{'LASTNAME'} = $lastName; $EmployeeInfo{$empkey}{'FIRSTNAME'} = $firstName; $EmployeeInfo{$empkey}{'AGE'} = $age; print "\n"; print "Employee ID: $employeeID\n"; print " Name: $firstName $lastName\n"; print " Age: $age\n"; } close EMPFIL; } } __END__
|
|---|