I don’t think I’ve ever written about Perl on my blog. But I have spent quite sometime programming with Perl. There is a lot of Perl code in Linux system tools and my exposure to Perl was primarily from integrating business logic via APIs and Linux admin stuff.
Back then the best source for learning Perl was the infamous Camel book series by O’Reilly, namely Learning Perl, Intermediate Perl and Mastering Perl.
Perl was my general go-to language because of my familiarity with it and it’s omnipresence on Linux systems. You’ll seldom find a Linux box without Perl, but you could find one without Ruby (or even Python) for that matter.
Principally, Ruby shares some things from Perl as in, both languages don’t impose a single way of doing things. In fact one of the motto’s of Perl is TMTOWTDI (There’s More Than One Way To Do It). And regex is first-class citizens in both languages. Used PCRE? That stands for Perl Compatible Regular Expressions.
Recently though, haven’t been doing much Perl – it’s mostly Ruby now, but I came across ARGF in Ruby which allows you to read files from standard input or those passed into command line arguments without having to deal with opening/closing file objects.
Here’s a Ruby script I use to create a CSV of shopping bill from my usual place.
#!ruby
gst_rate = nil
items = []
ARGF.each_line do |line|
  if /.*CGST@(?<cgst_rate>[0-9\.]+)%\s+SGST@(?<sgst_rate>[0-9\.]+)%/ =~ line
    gst_rate = cgst_rate.to_f + sgst_rate.to_f
  end
  if /(?<hsn_code>[0-9]{8})\s+₹.*/ =~ line
     parts = line.split(/[0-9]{8}/)
     amount = parts[1].strip[1..].to_f
     items.append(
       {
         name: parts[0].strip,
         hsn_code:,
         amount:,
         gst_rate:,
         total_amount: amount * (1 + gst_rate/100)
       }
     )
  end    
end
items.sort_by! { |item| item[:hsn_code] }
puts "Name,HSN Code,Amount,GST Rate,Total Amount"
items.each do |item|
  puts "#{item[:name]},#{item[:hsn_code]},#{item[:amount]},#{item[:gst_rate]}%,₹#{item[:total_amount]}"
endNotice how it uses ARGF.each_line. I updated it to use ARGF after I learned about it, previously I was accessing ARGV and then doing the usual File.open with it.
The Perl equivalent of this code would be something like this:
foreach(<>) {
        print "$_";
}The Perl operator <> for reading from STDIN does the same thing.
Along the same lines, I also discovered the Ruby interpreter has a very Perl-ish feature of using it as sed.
Perl:
$ perl -pe 's/print/quack/' test.pl  
foreach(<>) {
        quack "$_";
}Ruby:
$ ruby -pe '$_.gsub!(/print/, "quack")' test.pl
foreach(<>) {
        quack "$_";
}Even the option name is same -p 😀
Going further there’s also -a for auto split.
Ruby:
echo one two three | ruby -a -n -e 'print $F[0], $F[1], $F[2]'
onetwothreePerl:
echo one two three | perl -a -n -e 'print $F[0], $F[1], $F[2]'
onetwothreeI don’t think Ruby will replace Perl for quick shell tasks on general Linux boxes because it’s not installed by default, but still good to know.


