CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
Possibly a variable scope problem ...

 



reld
Novice

May 29, 2013, 2:53 AM

Post #1 of 9 (599 views)
Possibly a variable scope problem ... Can't Post

Hi, I am having trouble working out why the variable $name in the inner most while loop does not contain the value assigned to it in the while loop above.


Code
#!/usr/bin/perl 

use strict;
use warnings;

use Path::Class;
use autodie; # die if problem reading or writing a file

my $dir = dir("./"); # Read from current directory
opendir(DIR, $dir) or die $!; # Open the directory

while (my $file = readdir(DIR)) { # Read file from directory

next if ($file =~ m/^\./); # Skip . .. directories

if ( $file =~ /\.htm/ ) { # If file ends in .htm

my $file1 = $dir->file($file); # htm files

my $file2 = $dir->file("filelinks.txt"); # File to output to
my $file3 = $dir->file("file.txt"); #read from for data

# openr() returns an IO::File object to read from
my $file_handle1 = $file1->openr();
my $file_handle2 = $file2->open('>>'); # Append
my $file_handle3 = $file3->openr();

# Read in line at a time
while( my $line = $file_handle3->getline() ) {


my @cut = split ( /,/, $line );

my $name = $cut[0];
# $file_handle2->print($name) will work and put data1 into the output file
while ( my $line2 = $file_handle1->getline()) {

$file_handle2->print($name); #does not work
}



}
}
}


I am reading from a file.txt, and some .htm files. The file.txt has the form:


Code
data1,data2,data3 
data1,data2,data3
data1,data2,data3
...


I am trying to read from file.txt, and find matches from the value data1 in the .htm file.

I think this might be a scope problem. If anyone can help that would be greatly appreciated.


(This post was edited by reld on May 29, 2013, 3:45 AM)


reld
Novice

May 29, 2013, 3:28 AM

Post #2 of 9 (589 views)
Re: [reld] Possibly a variable scope problem ... [In reply to] Can't Post

As another example, using the same code. If I add:


Code
while( my $line = $file_handle3->getline() ) { 


my @cut = split ( /,/, $line );

my $name = $cut[0];


while ( my $line2 = $file_handle1->getline() ) {

if ( $line2 =~ /$name/ ) { # does not work

$file_handle2->print($line2);
}
}
}


The $name in the if ( $line2 =~ ) does not seem to contain a value. If I use a literal string instead the code works, so I know it has something to do with the $name variable.


(This post was edited by reld on May 29, 2013, 3:30 AM)


reld
Novice

May 29, 2013, 3:39 AM

Post #3 of 9 (585 views)
Re: [reld] Possibly a variable scope problem ... [In reply to] Can't Post

If I add a variable at the top:


Code
#!/usr/bin/perl 

use strict;
use warnings;

use Path::Class;
use autodie; # die if problem reading or writing a file

my $dir = dir("./"); # Read from current directory
opendir(DIR, $dir) or die $!; # Open the directory
my $match = "string"; ####### <------ Here


And change the code I posted in my second reply to:


Code
while( my $line = $file_handle3->getline() ) {  


my @cut = split ( /,/, $line );

my $name = $cut[0];


while ( my $line2 = $file_handle1->getline() ) {

if ( $line2 =~ /$match/ ) { # works

$file_handle2->print($line2);
}
}
}


The code works, so for some reason the variable $name is the problem. I've tried declaring the variable $name at the top as well, in the same place as $match in the code above, and it still doesn't work.


(This post was edited by reld on May 29, 2013, 3:47 AM)


reld
Novice

May 29, 2013, 4:46 AM

Post #4 of 9 (574 views)
Re: [reld] Possibly a variable scope problem ... [In reply to] Can't Post

I've narrowed the problem down to $cut[0]. If I set it equal to a string value, the code works and matches.


Code
my @cut = split ( /,/, $line ); 
$cut[0] = "string";



while ( my $line2 = $file_handle1->getline() ) {

if ( $line2 =~ /$cut[0]/ ) { # works

$file_handle2->print($line2);
}


If I instead write the code below:


Code
 my @cut = split ( /,/, $line ); 


$name = $cut[0];


while ( my $line2 = $file_handle1->getline() ) {

if ( $line2 =~ /$name/ ) { #doesn't work

$file_handle2->print($line2);
}
}


The variable $name doesn't seem to have a value. Something is going wrong with $cut[0].

After some more testing I think there is something I am doing wrong with the array @cut.


(This post was edited by reld on May 29, 2013, 5:19 AM)


BillKSmith
Veteran

May 29, 2013, 5:46 AM

Post #5 of 9 (561 views)
Re: [reld] Possibly a variable scope problem ... [In reply to] Can't Post

I do not see anything wrong with your code. I suspect a problem with your data.

Check all three files with your editor. If you do not find anything wrong, try printing the raw data to STDOUT as you read it (both input files).

It would help us if you would attach data files so we can duplicate your problem.
Good Luck,
Bill


reld
Novice

May 29, 2013, 6:12 AM

Post #6 of 9 (557 views)
Re: [BillKSmith] Possibly a variable scope problem ... [In reply to] Can't Post

I've attached some files. Put them all in the same directory for the PERL program to work.

data.txt contains the words separated by commas to be matched against the html code in 1.htm. I have written the PERL program to only match the first value for each line in the data.txt to keep it simple.

The print $name; statement in the inner most loop is only outputting "TLCTLC", whereas the print $name in the while loop above outputs "TLCModuleAddBBS".


(This post was edited by reld on May 29, 2013, 6:16 AM)
Attachments: main.pl (1.26 KB)
  data.txt (0.13 KB)
  1.htm (39.3 KB)


BillKSmith
Veteran

May 29, 2013, 7:33 AM

Post #7 of 9 (547 views)
Re: [reld] Possibly a variable scope problem ... [In reply to] Can't Post

There is nothing wrong with the variable $name. You are not reading your debugging output correctly.

Your outer loop outputs 'TLC'
The inner loop finds two copies of 'TLC' and prints each.

The inner loop is never enter again because you have reached the end of the file. All remaining output is comming from the outer loop.

You probably mean to close the htm file right after the inner loop completes. (You will also have to move the open to right before the start of the inner loop.)
Good Luck,
Bill


reld
Novice

May 29, 2013, 8:30 AM

Post #8 of 9 (544 views)
Re: [BillKSmith] Possibly a variable scope problem ... [In reply to] Can't Post

Thanks Bill, your right, I needed to close the htm file after the inner most loop, and then re-open it.

I thought that would be done automatically once the program went out of scope and started another iteration on the first while loop.

Thanks for the help!


(This post was edited by reld on May 29, 2013, 8:34 AM)


Laurent_R
Veteran / Moderator

May 29, 2013, 10:58 AM

Post #9 of 9 (530 views)
Re: [reld] Possibly a variable scope problem ... [In reply to] Can't Post

If you have to open and close a file each time you read some lines in another file, then your algorithm is probably far from optimal.

Consider reading once the inner file and storing it in memory (array or hash, for example), and then only to open the other file and look for what you need in memory.

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives