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

In this script, I get the error "Illegal modulus zero," but I can't see why it says that. Any ideas?
use strict; use warnings; if(!@ARGV){ my $line=1; $_=<>; handlefix(); open(INFILE, '<', $_) or die "\nCan't open $_: $!\n"; $_=<>; handlefix(); open(OUTFILE, '>', $_) or die "\nCan't open $_: $!\n"; while(<INFILE>){ print OUTFILE "_$line",": $_" if $line %% 5==0; print OUTFILE " $_" if $line %% 5!=0; $line++; } close INFILE && close OUTFILE; } if(@ARGV){ my $line=1; $_= shift @ARGV; handlefix(); open(INFILE, '<', $_) or die "\nCan't open $_: $!\n"; $_= shift @ARGV; handlefix(); open(OUTFILE, '>', $_) or die "\nCan't open $_: $!\n"; while(<INFILE>){ print OUTFILE "_$line",": $_" if $line %% 5==0; print OUTFILE " $_" if $line %% 5!=0; $line++; } close INFILE && close OUTFILE; } sub handlefix { chomp($_); $_=~s/"//g; $_=~s/\//\\/g; return $_; }

Thanks in advance!

Replies are listed 'Best First'.
Re: Modulus by zero?
by cLive ;-) (Prior) on Nov 16, 2006 at 23:03 UTC
    % not %%
      Wow, that was an easy fix. Thanks!
Re: Modulus by zero?
by pKai (Priest) on Nov 17, 2006 at 07:41 UTC

    Now that is interesting…

    >perl -MO=Deparse -e "$a if $b %% 5 == 0" $a if $b % %5 == 0; -e syntax OK

    So %5 is some sort of hash!?

    From perlvar
    Perl variable names may also be a sequence of digits or a single punctuation or control character. These names are all reserved for special uses by Perl; for example, the all-digits names are used to hold data captured by backreferences after a regular expression match.

    So the scalar variant of those digit vars are well-known, but the hash variant is "reserved" and serves no special purpose by now.

      The documentation is somewhat misleading at this point. Only all-digit scalars are read-only backreferences to captures, while all-digit hashes and arrays are not, not even read-only. But yes, they might be reserved :-)
      perl -le '@2 = 1..3; @1{qw(a b c)} = @2; print "$_=>$1{$_}" for keys % +1' c=>3 a=>1 b=>2

      Use of @1, %2 and so on is a common obfuscation technique.

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

      Also interesting is how the variable doesn't need to be declared, since it is automatically considered a package variable.

      >perl -Mstrict -e "@1 >perl -Mstrict -e "my @1 an't use global @1 in "my" at -e line 1, near "my @1" Execution of -e aborted due to compilation errors.

      Update: Ah, other special-like variables are like that too.

      >perl -Mstrict -e "%! >perl -Mstrict -e "my %! Can't use global %! in "my" at -e line 1, near "my %!" Execution of -e aborted due to compilation errors.
      IGNORE THIS

      I think it may be interpreting it as

        $b % undef % 5 == 0;

      undef would then be converted to zero before processing.

        The -p option to B::Deparse can be helpful when precedence questions arise:

        $ perl -MO=Deparse,-p -e '$a if $b %% 5 == 0' ((($b % %5) == 0) and $a); -e syntax OK

        Oops... nevermind... you're right...

        From the perl DB:

        DB<2> x \%5 + 0 HASH(0x500be0) empty hash