Perl in action (was Re: Ruby in Action)

Michael Brailsford brailsmt at yahoo.com
Thu Feb 15 21:27:37 MST 2007


I once worked with a self-taught programmer on a perl based web app.  We were having all sorts of odd dependency problems, and he wasn't convinced when I told him that we were having circular dependency issues.  (Side note:  Of course he also insisted on using the & sigil for all function calls.  I told him perl 4.x was incredibly old, and the syntax was deprecated, but he was utterly convinced it was more portable, despite me telling him it was exactly the opposite.  Anyway...)  I told him we needed to do an analysis of our module dependencies, and he balked at the idea.  He thought it would take weeks to go through all the modules and find any circular dependencies.  I promptly went back to my desk, ignored what he told me to do to start working on, something like create an Excel spreadsheet with the module names, etc....  I fired up vim, and banged out something like this in 2 hours (including testing and some trial and error graphviz config to make the graph prettier.

#!/usr/bin/perl

#some globbing-fu to get a list of files

print "graph {\n";
foreach my $file (@files) {
    open IN, $file or die;
        foreach my $line (<IN>) {
            if ($line =~ qr{ (?:use|require) \s+ ['"](.*?)['"] }xms ) {
             print "$file -> $1;\n";
            }
        }
    close IN;
}
print "}\n";

I ran it, redirected the output to a file, generated the graph, printed it and walked over to his desk, dropped it in front of him and said, "Done with the analysis of the whole code base."  Anyway, he was floored, and we cleaned up three or four indirect circular dependencies in a few days.  Anyway, I probably could have done it in ruby as well, but oh well.  I figured that was pretty terse, and not hyper-crap perl code.

You will have to excuse any errors in that, I was doing it from memory, and I did that a few years ago.

-Michael

----- Original Message ----
From: Hans Fugal <hans at fugal.net>
To: plug at plug.org
Sent: Thursday, February 15, 2007 3:15:36 PM
Subject: Ruby in Action

A biologist friend came to me and had some questions. She knows C and is
learning C++. Her questions were many, but it boiled down to "help, I've
fallen and I can't get up".

Her advisor advised her not to take classes on C++ or computer science,
but to learn by doing projects. He handed her a learning project to
convert a text representation of a bifurcating tree into a picture. He
said, use the factory pattern and a stack and the Boost graph library.
You can see where this is going. I helped her get a handle on tree data
structures, how they relate to graphs (so she could use boost graph
library if she wanted), and showed her how to use the STL stack and
talked a little about object oriented programming. It was a good
session, but it left her still overwhelmed at the amazing amount of work
it would be just to parse a string representation of a tree into a graph
structure (and I didn't have the heart to tell her about all the
backflips she'd probably have to do to get the boost graph library to
actually output something interesting).

Then I said, "Here's how I would do it in Ruby." We sat down at my
laptop and I whipped this out:

    # sample input: "((A,B),C)"
    puts "graph {"

    v = 0 # current vertex
    $stdin.each_byte { |b|
      b = b.chr # ASCII to string
      case b
      when '('
        if v == 0 # root node has no parents
      p = v = 1 
    else
      p = v # parent
      v = 2*p # left child
      puts "#{p}--#{v}"
    end
    puts "#{v} [shape=point]"
      when /[a-zA-Z]+/
    puts "#{v}--#{b}"
    puts "#{b} [shape=plaintext]"
      when ','
      when ')'
    v = v/2
      end
    }

    puts "}"

Yes, it needs to be modified to store a tree data structure for the real
work to come, but I was being agile and just writing the simple code to
tackle the task at hand.  Several lessons inherent here. First, agile
programming. Second, the evil of monstrosities like the boost graph
library. Third, the evil of C++. Fourth, the evil of trying to do in
code what can be done with the use of small specialized tools (like
graphviz in this case). Fifth, liberal parsing is often just fine (I
guess that's part of agility)

Thought you might enjoy. She did. She's going to try and convince her
advisor to let her use ruby (or perl or python or something not C++).
Unfortunately I don't think she'll be very successful. If he's a non-CS
type using libraries like Boost and the Factory pattern where it's not
needed, he's probably a self-taught software "engineer" who won't
believe things can or should be simple.

-- 
Hans Fugal ; http://hans.fugal.net
 
There's nothing remarkable about it. All one has to do is hit the 
right keys at the right time and the instrument plays itself.
    -- Johann Sebastian Bach

/*
PLUG: http://plug.org, #utah on irc.freenode.net
Unsubscribe: http://plug.org/mailman/options/plug
Don't fear the penguin.
*/






More information about the PLUG mailing list