in reply to Re: Recursive search
in thread Recursive search

why isn't my below code printing anything?It should search recursively in the .plf's and print them,not sure where is it going wrong?

#!/usr/bin/perl -w use strict; use warnings; my @recursive_plfs =(); my ($plf,$match_plf, $match_plf_name); my @plf_files = {"files.plf","orphans.plf"}; print @plf_files; my @file = "PLF=//source/perl/scripts/build/software/files.plf#30"; foreach my $plf (@plf_files) { print $plf; if (grep (/\Q$plf\E/i,@file)) { push @recursive_plfs,$plf; recrusion($plf); } } sub recursion { open my $DATA, '<',"$plf" or die "could not open '$plf' $!"; foreach (my $line = <$DATA>){ if(grep (/\.plf$/,$line)) { $match_plf = grep (/\.plf$/,$line); print $match_plf; $match_plf_name =~ /\/(\w+\.plf)/;#get only the plf name(files.plf) f +rom //source/perl/scripts/build/software/files.plf#30 push @recursive_plfs ,$match_plf_name; recursion($match_plf_name); } } } print @recursive_plfs;

Replies are listed 'Best First'.
Re^3: Recursive search
by Corion (Patriarch) on Dec 17, 2010 at 09:30 UTC

    Your code contains lots of syntax errors. For example the name of your subroutine is spelled in two different ways. This is wrong.

    In Perl, checking whether a single value matches a regular expression is best done by using the =~ operator, see perlop. Instead of

    grep(/.../, $item)

    use

    $item =~ /.../

    Also, it helps very much to understand code if it is indented properly. So, for each block, indent that block by (say) four spaces, until that block ends. This shows the structure that underlies your code. For example the first foreach loop will look like this if properly indented:

    foreach my $plf (@plf_files) { print $plf; if (grep (/\Q$plf\E/i,@file)) { push @recursive_plfs,$plf; recrusion($plf); } }

    This makes it far easier to spot what code belongs to which branch.

Re^3: Recursive search
by cdarke (Prior) on Dec 17, 2010 at 10:36 UTC
    my @plf_files = {"files.plf","orphans.plf"};creates a single element array containing a reference to a hash, because you used { } (called a 'composer'). You probably meant:
    my @plf_files = ('files.plf','orphans.plf');

    Your subroutine tests the same thing several times, try this:
    sub recursion { my $plf = shift; open my $fh, '<', $plf or die "could not open '$plf' $!"; foreach (my $line = <$fh>){ if($line =~ /(\w+\.plf)$/) { $match_plf_name = $1; next if $match_plf_name eq $plf; push @recursive_plfs ,$match_plf_name; recursion($match_plf_name); } } }
    You will notice that I don't use $DATA for filehandle name. This is because there is a reserved filehandle called DATA, so $DATA would be confusing. You will also notice that there is not a grep in sight. The capturing parentheses group is saved into $1.

    Finally, notice also the 'next' statement as an insurance against infinite recursion.
      Thanks cdark and corion but when I open the filehandle I only see the first line in the file getting stored,confused on what is wrong?
      my $plf = shift; print "\nPLF in recursion:$plf\n"; open my $fh, '<', $plf or die "could not open '$plf' $!"; foreach (my $line = <$fh>) { print "LINE:$line"; #prints ,just the first line if($line =~ /\/(.+?\.plf)$/) { print "LINE CONDITION:$line"; #never comes here #print $1; $match_plf_name = $1; next if $match_plf_name eq $plf; push @recursive_plfs ,$match_plf_name; recursion($match_plf_name); } } }

        perl mystery:

        You forgot perldoc chomp. Alternatively, you can remove the $ from your regex.

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.