The problem is that since your files have a different length, you will get some undefined values in your @lines
array. You cannot filter them out in the while condition, but you can filter them out afterwards, inside the loop:
while (grep defined, (my @lines = map {scalar <$_>;} @files)) {
@lines = map defined($_) ? $_ : "", @lines;
This will replace undefined values with the empty string, removing any uninitialized
warnings for those values, while keeping your tabs correctly aligned.
Note that your code actually does what it is meant to do, because undef
will stringify to the empty string. It is only because you have warnings on that you get the warnings about it. However, it is a very good idea to have warnings on, so errors such as this can be found and fixed properly.
You should note that using open
without checking its return value is not a good idea, unless you explicitly handle the failed cases. The proper way is to do this:
open $files[@files], '<', $_ or die $!;
For simplicity one can also use
use autodie;
The autodie
module will produce fatal errors for critical function calls such as open
.