in reply to "Use of uninitialized value in pattern match (m//)" warning, doing a grep on 2D array

G'day soblanc,

It's not clear whether undef values have erroneously crept into your data and you want to fix that; or if undef values are quite valid and you simply want to skip them when filtering.

You haven't shown how you create @matrix so some guesses are needed here. The code below is effectively in two parts:

  1. A variety of ways that undef values could have crept into your data. This is by no means a complete list of possibilities. It should give you hints as to what to look for when fixing the data.
  2. How to skip undef values when filtering. Based on your last post (Sort a matrix by row), and "my script handles millions of lines" (in this post) it looks like you're dealing with biological data; accordingly, you'll want to pay attention to code efficiency — not just for this small snippet but for your entire program. grep EXPR, LIST (which I used) is faster than grep BLOCK LIST (which you used): see grep. You can test that for yourself with Benchmark.
#!/usr/bin/env perl use v5.26.3; use warnings; my @matrix; my ($col2, $col3) = qw{column2 column3}; my $keep_re = qr{1}; my $fmt = "%d: %-5s %s %s\n"; { my $col1; push @matrix, [$col1, $col2, $col3]; } { my $col1 = []; push @matrix, [$col1->[0], $col2, $col3]; } { my @col1s; my $elem1; push @col1s, $elem1; push @matrix, [$col1s[0], $col2, $col3]; } { my @col1s = (1); pop @col1s; push @matrix, [$col1s[0], $col2, $col3]; } { my @col1s = (2); my $elem1; unshift @col1s, $elem1; push @matrix, [$col1s[0], $col2, $col3]; } for (1, 2, 12, 100, 234) { push @matrix, [$_, $col2, $col3]; } say '*** Original:'; my @original = @matrix; for (0 .. $#original) { $original[$_][0] //= 'undef'; printf $fmt, $_, @{$original[$_]}; } say '*** Filtered:'; my @filtered = grep +(defined $_->[0] and $_->[0] =~ $keep_re), @matrix; for (0 .. $#filtered) { $filtered[$_][0] //= 'undef'; printf $fmt, $_, @{$filtered[$_]}; }

Output:

*** Original: 0: undef column2 column3 1: undef column2 column3 2: undef column2 column3 3: undef column2 column3 4: undef column2 column3 5: 1 column2 column3 6: 2 column2 column3 7: 12 column2 column3 8: 100 column2 column3 9: 234 column2 column3 *** Filtered: 0: 1 column2 column3 1: 12 column2 column3 2: 100 column2 column3

While I'm not advocating the use of "no warnings 'uninitialized';" in this instance, I will point out that the effect of the warnings pragma is lexically scoped. When it's appropriate, turn off warnings in as small a scope as possible.

use warnings; ... # all warnings in effect here { no warnings 'XYZ'; # all warnings except XYZ in effect here } # all warnings in effect here

— Ken

  • Comment on Re: "Use of uninitialized value in pattern match (m//)" warning, doing a grep on 2D array
  • Select or Download Code