Global symbol

Hi. I am getting the following error. It has to do with the globalness of the %hash. How can I fix that?

C:\Users\Bill\Desktop\LPTHW>perl freqTable.pl sampleForGraphing.csv
Variable "%hash" is not imported at freqTable.pl line 45.
Global symbol "%hash" requires explicit package name at freqTable.pl line 45.
Execution of freqTable.pl aborted due to compilation errors.


#!/Perl/bin/perl
use strict;
use warnings;

# create a list of files or just one file.
#this time I will just use one and so I will read it in from the command line.


# create a sub to read a list of files.
# but from within there I will have to call another function called read_line and so I have to
#define it before this one I think.

sub read_line { #this sub will be called from the other sub and the other sub will pass it
				# a line of text to work on. So this one will capture that line with shift;
				#but actually shift; will be called from within the split function and the 
				#result of the split function will create a list.
		our %hash;  #I think the fact that this is global is very important
					#because if not you would only get a frequency table for one line.
		
		my @list = split " ", shift;  #note: I think this is the same as 
									  # my @list = split(" ", shift);  ???Maybe.
		foreach my $word (@list) {
			$hash{$word}++;
			}
}

sub print_hash {
				our %hash = shift;
			while((my $key, my $value) = each( %hash)) {     
			
			print $key, $value;
			 }

}
sub read_file {
#I will call this file with @ARGV as the argument list.
#The only argument I need is the file name and so:
my $fileName = shift;
# Now you need to open the file
open (FILE, $fileName) || die "couldn't open $fileName";

while( my $line = <FILE>) { #do something.. I will use another subroutine to tell it what to do.
	read_line $line;
	}
print_hash %hash;
}

# so now both functions have been defined. Now we need to call the "first" one (the outside one).
read_file @ARGV;

Open in new window

onyourmarkAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

TintinCommented:
Declare any globals just once.

Do this at the beginning of the script.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
TintinCommented:
Although, in your case, there's no need to use 'our'.  'my' is sufficient.
0
TintinCommented:
In the code you posted, are you using subroutines as a learning exercise as there's no real point in using them for what you are doing.
0
Exploring SQL Server 2016: Fundamentals

Learn the fundamentals of Microsoft SQL Server, a relational database management system that stores and retrieves data when requested by other software applications.

onyourmarkAuthor Commented:
Hi. I am attaching the file I tried the code on. I declared %hash just once now. I have also attached the new code.

I get this error

C:\Users\Bill\Desktop\LPTHW>perl freqTable2.pl sampleForGraphing.csv
Odd number of elements in hash assignment at freqTable2.pl line 29, <FILE> line 150.
Use of uninitialized value $value in print at freqTable2.pl line 32, <FILE> line 150.
Army?,Colombo
#!/Perl/bin/perl
use strict;
use warnings;

# create a list of files or just one file.
#this time I will just use one and so I will read it in from the command line.


# create a sub to read a list of files.
# but from within there I will have to call another function called read_line and so I have to
#define it before this one I think.

my %hash;
sub read_line { #this sub will be called from the other sub and the other sub will pass it
				# a line of text to work on. So this one will capture that line with shift;
				#but actually shift; will be called from within the split function and the 
				#result of the split function will create a list.
		#our %hash;  #I think the fact that this is global is very important
					#because if not you would only get a frequency table for one line.
		
		my @list = split " ", shift;  #note: I think this is the same as 
									  # my @list = split(" ", shift);  ???Maybe.
		foreach my $word (@list) {
			$hash{$word}++;
			}
}

sub print_hash {
				%hash = shift;
			while((my $key, my $value) = each( %hash)) {     
			
			print $key, $value;
			 }

}
sub read_file {
#I will call this file with @ARGV as the argument list.
#The only argument I need is the file name and so:
my $fileName = shift;
# Now you need to open the file
open (FILE, $fileName) || die "couldn't open $fileName";

while( my $line = <FILE>) { #do something.. I will use another subroutine to tell it what to do.
	read_line $line;
	}
print_hash %hash;
}

# so now both functions have been defined. Now we need to call the "first" one (the outside one).
read_file @ARGV;

Open in new window

SampleForGraphing.csv
0
TintinCommented:
Here's the version that uses no subroutines (which for this purpose makes more sense) and proper formatting (makes it much easier to read)


use strict;
use warnings;

my %words;

foreach my $filename (@ARGV) {
  open my $FILE, '<', $filename or die "Can not open $filename because $!\n";

  while (<$FILE>) {
     foreach my $word (split) {
        $words{$word}++;
     }
  }

  close $FILE;

  while ( my ($key,$value) = each %words) {
     print "key is $key  value is $value\n";
  }
}

Open in new window

0
onyourmarkAuthor Commented:
Hi. Thanks. I am confused about this
foreach my $word (split) {
        $words{$word}++;

What is split doing? It is not a function is it?
0
TintinCommented:
split is a builtin Perl function.

By default, split will split a string on whitespace.

0
onyourmarkAuthor Commented:
Thanks. What is the other argument? What is it splitting?
0
TintinCommented:
split takes up to three parameters

       split /PATTERN/,EXPR,LIMIT
       split /PATTERN/,EXPR
       split /PATTERN/


Let's look at some examples.

my $string='one two three';
my @array = split ' ',$string;

this would split $string based on a space, so @array would end up with three elements, ie:

$array[0]  would contain: one
$array[1]  would contain: two
$array[2]  would contain: three


does that help?

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Perl

From novice to tech pro — start learning today.