title: How can I write Perl that doesn't look like C?
body: <p>My co-workers complain that my Perl looks too much like C, which is natural since I program in C most of the time, and Perl just a bit.  Here's my latest effort. I'm interest in Perl that is easy to understand. I'm a bit of a Perl critic, and have little tolerance for cryptic Perl. But with readability in mind, how could the following code be more Perlish?</p>
  
  <p>It's goal is to do a traffic analysis and find which IP addresses are within the ranges given in the file "ips".  Here's my effort:</p>
  
  <pre><code>#!/usr/bin/perl -w
  
  # Process the files named in the arguments, which will contain lists of IP addresses, and see if 
  # any of them are in the ranges spelled out in the local file "ip", which has contents of the
  # form start-dotted-quad-ip-address,end-dotted-quad-ip_address,stuff_to_be_ignored
  use English;
  
  
  open(IPS,"ips") or die "Can't open 'ips' $OS_ERROR";
  
  # Increment a dotted-quad ip address
  # Ignore the fact that part1 could get erroneously large.
  sub increment {
      $ip = shift;
  
      my ($part_1, $part_2, $part_3, $part_4) = split (/\./, $ip);
      $part_4++;
      if ( $part_4 &gt; 255 ) {
          $part_4 = 0;
          ($part_3++);
          if ( $part_3 &gt; 255 ) {
              $part_3 = 0;
              ($part_2++);
              if ( $part_2 &gt; 255 ) {
                  $part_2 = 0;
                  ($part_1++);
              }
          }
     }   
      return ("$part_1.$part_2.$part_3.$part_4");
  }
  
  # Compare two dotted-quad ip addresses.
  sub is_less_than {
      $left = shift;
      $right = shift;
  
      my ($left_part_1, $left_part_2, $left_part_3, $left_part_4)     = split (/\./, $left);
      my ($right_part_1, $right_part_2, $right_part_3, $right_part_4) = split (/\./, $right);
  
  
      if  ($left_part_1 != $right_part_1 ) { 
          return ($left_part_1 &lt; $right_part_1);
      }   
      if  ($left_part_2 != $right_part_2 ) { 
          return ($left_part_2 &lt; $right_part_2);
      }   
      if  ($left_part_3 != $right_part_3 ) { 
          return ($left_part_3 &lt; $right_part_3);
      }
      if  ($left_part_4 != $right_part_4 ) {
          return ($left_part_4 &lt; $right_part_4);
      }
      return (false);  # They're equal
  }
  
  my %addresses;
  # Parse all the ip addresses and record them in a hash.   
  while (&lt;IPS&gt;) {
      my ($ip, $end_ip, $junk) = split /,/;
      while (is_less_than($ip, $end_ip) ) {
          $addresses{$ip}=1;
          $ip = increment($ip);
      }
  }
  
  # print IP addresses in any of the found ranges
  
  foreach (@ARGV) {
      open(TRAFFIC, $_) or die "Can't open $_ $OS_ERROR";
      while (&lt;TRAFFIC&gt; ) {
          chomp;
          if (defined $addresses{$_}) {
              print "$_\n";
          }
      }
      close (TRAFFIC);
  
  }
  </code></pre>