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

Hello, Perl Monks! I've fixed the code I'm about to show you, but I cannot understand why the original code was not working. For background, this script used to run just fine, but now, without explicitly defining the variables, it returns an undefined %chrsize hash. I've inherited this script and I've been tasked with fixing it. It was written without "use warning" and "use strict". here is the original code:

use File::Basename; my $filename=fileparse($ARGV[0]); $win=1000; # window size 1kb $L=`/scratch/xli91_lab/bin/rpyc/sumcol $ARGV[2] 2`; # total nt of geno +me excluding chrUext and chrM $N=$L/$win; $ratio=$ARGV[1]*0.01; open IN,$ARGV[2]; while(<IN>) #there was no $_[1]; it was undef/blank. After explicitly +declaring/storing in @array, it worked { chomp; split(/\t/); $chrsize{$_[0]}=int($_[1]/$win); }

Here is how I fixed it:

use File::Basename; my $filename=fileparse($ARGV[0]); $win=1000; # window size 1kb $L=`/scratch/xli91_lab/bin/rpyc/sumcol $ARGV[2] 2`; # total nt of geno +me excluding chrUext and chrM $N=$L/$win; $ratio=$ARGV[1]*0.01; open IN,$ARGV[2]; while(<IN>) { chomp(my $line= $_); my @array = split(/\t/, $line); print"$array[0]\n"; #array[1] are numbers #array[2] are chr names $chrsize{$array[0]}=int($array[1]/$win); }

On an unrelated note: This is part of a perl script that USED to work without throwing errors until a system security update on our university's linux cluster. on an unrelated note, do you believe that the larger script may be throwing errors now due to permissions issues? Why else would a working script suddenly stop working after tightening security?

Replies are listed 'Best First'.
Re: What is the logical error here (Fixed, but I want to understand)
by haukex (Archbishop) on Jun 07, 2019 at 13:38 UTC

    If you look at the documentation of split from 5.10.1: "In scalar and void context it splits into the @_ array." Then, from here: "split() no longer modifies @_ when called in scalar or void context. In void context it now produces a "Useless use of split" warning. This was also a perl 5.12.0 change".

      Does "split() no longer modifies @_" mean that it will not return the output of its call to the variable @_? As in,  split(\/t\, $line) will not work, but  my @array = split(\/t\, $line) will work?
        Does "split() no longer modifies @_" mean that it will not return the output of its call to the variable @_? As in, split(\/t\, $line) will not work, but my @array = split(\/t\, $line) will work?

        Yes, that's it. In your first piece of code, you were using split in "void context" because you weren't doing anything with the return value, in which case Perl before v5.12 used to store split's return value in the @_ variable, which is why you could access it via $_[0] etc. That is no longer the case, and you need to use split's return value explicitly, such as by storing it in an array, like you did in your second piece of code.