averlon
averlon

Reputation: 349

perl process inlude files recursively

I would like to process files recursively.

I have a config file, and this config file can include an "include" statement. Once the include-statment is identified, the file shall be processed. It could happen, that in the file processed again an include-statement can show up.

So something like this:

For this to manage I have created a subroutine: Update ---- call for sub updated!

my $av_fn_FH;
my $av_tmp_LINE;
my @av_arr_FN;
sub processfile
{
  open($av_fn_FH, "<", "$_[0]")
  while($av_tmp_LINE = readline($av_fn_FH)) 
  { 
    if ( substr($av_tmp_LINE,0,7) eq "include" )
    {
      @av_arr_FN = split(" ", $av_tmp_LINE); # get the filename from the include statement
      processfile($av_arr_FN[1]); # process the include file
    }
    # do something with "normal" lines
  }
  close($av_fn_FH);
}

This recursive calling of the subroutine does not work. Once comming back from the subroutine the HANDLE is reported as closed.

The docu for the open statement says: "Associates an internal FILEHANDLE with the external file specified by EXPR." I expected the FILEHANDLE as unique!

I would apreciate some hints how to get this done!

Upvotes: 1

Views: 77

Answers (1)

Jim Davis
Jim Davis

Reputation: 5290

Your filehandle is declared outside of the subroutine; so you over-write the value when you open a new config file, and then close it.

sub processfile
{
    open(my $fh, "<", $_[0])
        or die "Can't open $_[0]: $!";

    while(my $line = readline($fh)) { 
        if ($line =~ /^include\s+(\S+)/) {
            # $1 is the filename after "include "
            processfile($1);   # process the include filename
            next; # skip "normal" stuff below
        }
        # do something with "normal" lines
    }
    close($fh); # optional; closes anywhen when $fh goes out of scope
}

In general, you want to declare your variables in as small a scope as possible where they're actually used.

Upvotes: 2

Related Questions