Oh, one bad on my part, i meant for the "
while (<FILE>)" to be replaced by your while loop, since it contained the counter variable you needed. I'm not sure what your routines "
&open_file" or "
&read_file" do, so you may even want to get rid of those alltogether. Opening and reading files are really easy to do in perl, and you could quickly figure out how to do it correctly. If you don't, you'll probly have to leave in the original code, so you can just take my "
while ..." part out of your code.
Next, the "my" variable declaration limits the varible to only exist inside the innermost brakets that contain it (well, that's the simplest explaination), so in order for other routines to be able to use it, you can do a couple of different things.
1) You can declare the variable in the outermost part of your program, without any brackets around it, preferably at the beginning of your script for readability. Then, whenever something inside brackets does something to that variable, it affects the global instance, instead of just on inside of the brackets.
2) You could redesign your program with more modularity in mind, and have various subroutines created such that the value they return is what needs to be assigned to a variable, be it reference or whatever.
I'll pick the easier of the two i've mentioned, the first, and show you what i mean.
When your script declares "
my @sorted ..." that variable is only visible inside of the brackets where it is declared. Later, when you run the "
foreach (@sorted)", there is no variable to access (and this would produce a warning of some sort if you have "
use strict;" on.).
What you need to do is predeclare the variable on it's own line outside of any enclosing brackets. just "
my @sorted;" on a line by itself is good enough. Then, remove the "my" in front of where i had it declared, so it just reads "
@sorted = ...". This way, the @sorted array will be modified on a (basically) global level, and when you access it later with the foreach, it'll have the correct values stored in it.
Next, you're right to see that the sorted table data is then stored in "@sorted", so if you want access to that data, you'll use it, not "@tabledata". So, for the next part, i'll use "@sorted" as you should.
Lastly, you need to dereference the two-dimentional array. This is a little strange bit of concept to new programmers, and is a bit of work to get used to. If, after reading what i write, you still don't get it, i'd suggest first "perldoc perlrefs" (i think that's correct), and second, the camel book (O'Reilly's "Programming Perl"

, has a great chapter on referencing/dereferencing.
Basically, the data structure i had you make is graphically a two-dimentional array; a spreadsheet. It's coded by having one array as the parent array, and another array (in this case, an anonymous array, one without name) for every entry in the parent array. Arrays can actually only have scalar values as entries, not whole arrays, so this means that each entry in the parent is actual a reference to an array. Anyway, this translates easily to your file, where every line is an record, and each record has multiple entries. What the code does is it maps all the entries into an array, and then puts that array into place in the parent.
So, in the parent, the first record (the first line of your file) is "
$sorted[0]", the second record is "
$sorted[1]" and so on. the first entry in the first record (that is, the first entry in the first line) is accessed as follows: first, identify the record it's in, then identify the entry you want. Here's how this looks:
[tt]
$sorted[0]->[0][/tt]
The second entry in the first record is:
[tt]
$sorted[0]->[1][/tt]
The third entry in the first record is:
[tt]
$sorted[0]->[2][/tt]
and,
the first entry in the second
[tt]
$sorted[1]->[0][/tt]
As you can see, the first number represents the record, the second represents the entry number.
Now, you'll be running a foreach loop around the sorted array. That means each time it runs through, it'll be dealing with the reference to the array that is each record. This means you'll need to dereference the entries on the fly.
Another thing you'll need to be aware of is that you won't be able to get the right results by accessing the actual data, as you had been doing. The foreach loop will set the variable "$_" to the element of the loop you'll be dealing with each pass.
[tt]
foreach (@sorted) {
# see if SECOND field matches query
if ($_->[1] =~ /^$query$/i) {
# print the THIRD field
print "$_->[2]";
# print the FOURTH field
print "<i><b>$_->[3]</b></i>";
# print description
$listing = "- $_->[4],
$_->[5],
$_->[6],
$_->[7],
$_->[8]";
print "$listing";
print " \($_->[1]\) ";
$counter++;
}
}
[/tt]
This code will correctly dereference things.
A couple of last notes. First: I'm not sure what your $counter is doing, so i'll let you figure out the logic of that. Second: If you need to know more about what's going on inside your program, but don't really want to learn the debugger, you put "
print $_;", or any variable name, for that matter, just to make sure it has a value. On that note, a reference will print out something like the following "
ARRAY (0x8b1d4)" or something, which means you need to dereference something first. Third: If you do use "
use strict;", you'll need to explicitly declare all variables before you use them. while this is very good practice, your code doesn't do so already, so you would have to modify it some. This would, however, make for an easier time debugging it. Lastly: although not a quick weekend read, the camel book (O'Reilly's "Programming Perl"

would really help your programming efforts. go through chapters that seem to pertain to the problems your having, or just start with the first and move forward.
Okay, now i should get back to work. s-) Glad i've been of assistance. "If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito."