
japhy
Enthusiast
Mar 7, 2000, 3:53 AM
Post #4 of 7
(580 views)
|
I found a couple points in your code that could be causing the errors, so I'll reproduce your code and pinpoint the trouble-spots. It IS very good that you use -w and the CGI module. You don't need to "use vars", though, if you're not doing "use strict" (which you might not be ready for). <BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR> #!/usr/local/bin/perl -w use vars qw(%config $in); use CGI qw(:cgi); use CGI::Carp qw(fatalsToBrowser); $in = new CGI; %config = ( lock => 1, member_text => "/data1/hypermart.net/tplg/members/mem.txt", ); $action = $in->param('action'); $start = $in->param('start'); print $in->header('text/html'); open(FILE, "$config{'member_text'}") or &die("$!"); </pre><HR></BLOCKQUOTE> Here's the first iffyness. As of Perl 5, you no longer need to put an ampersand (&) in front of calls to non-builtin subroutines, and here, you're using it in front of a built-in, which makes it try to call a user-defined function. Remove the &, and one problem will be fixed. <BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR> if(%config{'lock'} == 1) { flock FILE,2; } </pre><HR></BLOCKQUOTE> To get at hash elements, either use $hash{KEY} or @hash{KEY1,KEY2,KEY3,...}. Doing %hash{KEY} in the way you do there would elicit the following error from Perl: Can't use subscript on hash deref at -e line 1, near "{KEY}" (Did you mean $ or @ instead of %?) Which is Perl's way of saying "hashes aren't used like that." You'd want to say: <BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR> if ($config{lock}) { flock FILE, 2 } </pre><HR></BLOCKQUOTE> You don't need quotes around a "simple" hash key (one that's just a string of letters, underscores, and numbers), and you don't need to test for equivelency to 1, you just need to see if the value is true. <BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR> @lines=<FILE>; close(FILE); $count=0; foreach $line (@lines) { $count++; ($name, $email) = split(/\|/,$line); } </pre><HR></BLOCKQUOTE> It appears you've forgotten to actually put these in the @name and @email arrays. And before you think of using $name[$count] and $email[$count], please remember that arrays in Perl start at 0, and the preferred method of placing an element at the end of an array is via the push() function. And it's nicer (and smarter) to not slurp an entire file into an array, if you can avoid it: <BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR> while (<FILE> ) { # line is in $_ chomp; # remove the ending newline ($name,$email) = split /\|/; # split() defaults to splitting on $_ push @name, $name; push @email, $email; } close FILE; </pre><HR></BLOCKQUOTE> And in your final section of the code: <BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR> $i=1; $x=1; while (($x<11) and ($i<=$count)) print "$i - Name: $name[$i]<br>\n"; print " Email: $email[$i]\n<P>\n"; $i++; $x++; } </pre><HR></BLOCKQUOTE> First (and syntax-wise), you're missing the opening { on your while statement. But from a getting-things-done point of view, you should probably change this code a bit. You only want to print (at most) the first 10 sets of information, right? Then you could have done a few things differently: save only the first ten sets of information, and then stop processing the file; or you could get rid of that $x variable by testing $i twice (make sure it's less than 10 AND less than the number of elements in the arrays): <BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR> for ($i = 0; $i < 10 and $i < @name; $i++) { print "$i - Name: $name[$i]<br>\n"; print "Email: $email[$email]<br><br>\n"; } </pre><HR></BLOCKQUOTE> By testing "$i < @name", we are using @name in scalar context to get the NUMBER of elements in it. If you want to use the first method I discussed (saving only the first 10 records), then you can change the program (from the while-loop until the end) to: <BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR> while (<FILE> ) { chomp; ($name,$email) = split /\|/; push @name, $name; push @email, $email; # leave the loop if there are 10 # elements in the @name array last if @name == 10; } for $i (0 .. 10) { print "$i - Name: $name[$i]<br>\n"; print "Email: $email[$email]<br><br>\n"; } </pre><HR></BLOCKQUOTE> And finally, depending on whether or not you'll end up really needing those arrays, you can just print the name/email stuff IN the while loop AS you get the stuff: <BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR> $i = 0; while (<FILE> ) { chomp; ($name,$email) = split /\|/; print "$i - Name: $name<br>\n"; print "Email: $email<br><br>\n"; $i++; last if $i == 10; # leave if we've seen 10 records } </pre><HR></BLOCKQUOTE> If anything I've suggested seems over your head, don't rush to using it, and instead, stick with things you're more familiar with. We can discuss this on the forum so that other people that might not totally get this can better understand it.
|