rocketperl has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I am trying to print the values of hfr_genes.txt only if it is present in gene_list.txt but the code is not working and i get the error 'use of uninitialized value in array'. pls help me. thanks.
#!/usr/bin/perl use 5.010; use strict; use warnings; open GL,'gene_list.txt'; open HFR,'HFR_genes.txt'; use List::MoreUtils qw(first_index indexes); my @gl=<GL>; my @hfr=<HFR>; chomp @gl; chomp @hfr; my $a; for($a=0;$a<=scalar(@hfr);$a++) { my @matching_indices=indexes {$hfr[$a]}@gl; my @matching_values=@gl[@matching_indices]; print "$matching_indices[$a]"; }

Replies are listed 'Best First'.
Re: use of uninitialized value in array
by toolic (Bishop) on Aug 02, 2013 at 16:06 UTC

    Tip #2 from the Basic debugging checklist: print. Add more prints inside your for loop. It is likely that $a is beyond the last element of the @matching_values array.

    for($a=0;$a<=scalar(@hfr);$a++) { my @matching_indices=indexes {$hfr[$a]}@gl; my @matching_values=@gl[@matching_indices]; print "a=$a\n"; use Data::Dumper; print Dumper(\@matching_indices); print "$matching_indices[$a]"; }

      $a is definitely going beyond the end of @hfr. Use < instead of <= in the loop test to avoid this.

      Oh, and don't use $a as a variable name. Nor $b for that matter.

      Update: For some reason I had missed that Cristoforo had already mentioned this. Sorry for the waste of bandwidth.

      Thanks for your help. Will go through the tutorials. but i still get the same error with your idea too. anyway will see if i get any help in the tutorials.
Re: use of uninitialized value in array
by Cristoforo (Curate) on Aug 02, 2013 at 16:46 UTC
    You are getting the last index for the array 1 past the end of the array.
    for($a=0;$a<=scalar(@hfr);$a++)
    That should be:
    for($a=0;$a<scalar(@hfr);$a++)
    And you could also leave out the scalar because the @hfr array is being used in a scalar context and doesn't need to be cast explicitly to scalar.

    There seem to be some other problems as well.

    my @matching_indices=indexes {$hfr[$a]}@gl;
    I think this should be
    my @matching_indices=indexes {$hfr[$a]eq $_}@gl;
    I'm not sure the other statements will give the result you want. For example, print "$matching_indices[$a]"; is using the loop index and most likely index beyond the bounds of the array, also a possible source of the 'use of uninitialized value in array' warning.
Re: use of uninitialized value in array
by ww (Archbishop) on Aug 02, 2013 at 19:13 UTC

    ...and check that your opens actually work (against possible typo in name, CWD is wrong dir; etc):

    open (HFR, '<', 'HFR_genes.txt') or die "Can't open for reading HFR_ge +nes.txt, $!";

    Updated to correct file name; miscopied from OP.

    My apologies to all those electrons which were inconvenienced by the creation of this post.
Re: use of uninitialized value in array
by Cristoforo (Curate) on Aug 02, 2013 at 21:01 UTC
    I thought I'd provide another solution. It uses a hash, %seen, to serve as a lookup for genes in 'HFR_genes.txt' that are also in 'gene_list.txt'.
    #!/usr/bin/perl use 5.010; use strict; use warnings; my $gene_list = 'gene_list.txt'; open GL, "<", $gene_list or die "Unable to open $gene_list because $!" +; my %seen; while (my $gene = <GL>) { $seen{$gene}++; } close GL or die "Unable to close $gene_list because $!"; my $hfr = 'HFR_genes.txt'; open HFR, "<", $hfr or die "Unable to open $hfr because $!"; while (my $gene = <HFR>) { print if $seen{$gene}; } close HFR or die "Unable to close $hfr because $!";
    Chris

    Update: If both files have unique lines, the code could be shortened to:

    my %seen; print grep $seen{$_}++, <>;
    With the command line supplying the 2 files: perl your_program.pl gene_list.txt HFR_genes.txt
Re: use of uninitialized value in array
by BillKSmith (Monsignor) on Aug 02, 2013 at 19:41 UTC
    Check the FAQ for an alternate method. perldoc -q "intersection of two arrays"
    Bill