Reputation: 51
I tried to count the total number of words which are present in the file. The code below is showing 0 words as an output. Please help me fix this problem.
This code is saved in Countsample.pm
:
package Countsample;
use strict;
use base"Exporter";
#use 5.010;
our @EXPORT=();
our @EXPORT_OK=qw(word_count);
sub word_count
{
open(IP,"test1.txt");
while(my $line=<>)
my $word_count;
my @words_on_line = split;
$word_count+= @words_on_line;
print"File contains $word_count words\n";
}
1;
Now in main program which is saved in Countsample1.pl
:
#!/usr/bin/perl
use Countsample qw(word_count);
word_count();
exit;
The output I am getting is
syntax error at Countsample.pm line 14, near ") my " Global symbol "$word_count" requires explicit package name at Countsample.pm line 14. Global symbol "$word_count" requires explicit package name at Countsample.pm line 18. Global symbol "$word_count" requires explicit package name at Countsample.pm line 21. Compilation failed in require at Countsample1.pl line 3. BEGIN failed--compilation aborted at Countsample1.pl line 3.
Upvotes: 0
Views: 538
Reputation: 69314
Here's the error I get:
$ perl Countsample1.pl
syntax error at Countsample.pm line 14, near ")
my "
Global symbol "$word_count" requires explicit package name at Countsample.pm line 14.
Global symbol "$word_count" requires explicit package name at Countsample.pm line 18.
Global symbol "$word_count" requires explicit package name at Countsample.pm line 21.
Compilation failed in require at Countsample1.pl line 1.
BEGIN failed--compilation aborted at Countsample1.pl line 1.
Lines 13 and 14 are:
while(my $line=<>)
my $word_count;
Your while
loop needs a block of code. And blocks of code are delimited with braces. I think those lines (and the few following ones) should be:
my $word_count;
while(my $line=<>) {
my @words_on_line = split;
$word_count+= @words_on_line;
}
I've also moved my $word_count
outside of the loop - you really don't want to reset it to zero on each loop iteration, do you?
Hmm.. now when I run it it just hangs. What could be wrong? That usually means either an infinite loop or a program waiting for input.
In this case, it's the program waiting for input.
while(my $line=<>)
This reads from STDIN (ok, yes, actually it reads from either STDIN or the files which have been passed on the command line - but there weren't any in this example, so STDIN it is). Presumably, you want it to read from the filehandle that have just opened. So use that instead.
while(my $line=<IP>)
Now it doesn't hang. But it says that my test file contains 0 words. And that's wrong.
Ah the problem is here. my $line=<IP>
puts the line into $line
. But you split the line with just split
, which works on $_
, not $line
. Let's remove the my $line=
so that the while
loop puts the data into $_
.
while (<IP>)
Now the program says that my file contains 5 words. Which is better than zero, but probably not right. So there's likely to be a logic problem.
Now you start debugging you logic...
Update: Actually, no. My file did contain only five words. So the logic is sound. Time to start adding more features. And perhaps modernising your code - for example replacing your old-style open()
statement (open(IP,"test1.txt")
) with something more modern (open my $ip, '<', "test1.txt")
). Also check the return value from open()
- open my $ip, '<', "test1.txt") or die $!
.
Upvotes: 1
Reputation: 91518
There are some syntax errors in your script :
sub word_count {
open(my $IP, '<', 'test1.txt') or die $!;
# ^^^^^^^^^ always test the result of open
my $word_count;
# you must defined the counter outside of the while loop
while(my $line=<$IP>) {
# ^ you missed begin while bloc
my @words_on_line = split ' ', $line;
$word_count+= @words_on_line;
} # and close while bloc
# print the total outside of the loop
print"File contains $word_count words\n";
}
Upvotes: 2
Reputation: 118166
You need to give your program either a file or some input. E.g.
perl Countsample1.pl Countsample.pm
will count the words in Countsample.pm
Also, you want while (my $line = <>)
instead of the open
. Did you notice how you never read from anything? I am assuming this is homework, so I am not going to post a completely re-written script.
Now, you must decide whether you are going to count words in just test1.txt
, or anything given on the commandline or STDIN
(that's what using <>
means).
Assuming the latter, your word_count
subroutine becomes rather simpler:
sub word_count {
my $count;
while (my $line=<>) {
my @words_on_line = split ' ', $line;
$count += @words_on_line;
}
print "File contains $count words\n";
return; # don't accidentally use the return value of print as count
}
Of course, it would be better to just return the count from this subroutine and have the caller decide what to do with the return value.
PS: Your shebang line is wrong. It should be #!/usr/bin/perl
if you want to use the system perl
.
PPS: You don't need to inherit from Exporter. In most cases,
use Exporter qw( import );
is all you need.
PPPS: Don't export stuff by default. Instead, do:
our @EXPORT = (); # nothing is exported by default
our @EXPORT_OK = qw( word_count ); # word_count is exported if asked
and then use
use Countsample qw( word_count );
so you can invoke Countsample::word_count
as just word_count
.
Upvotes: 2