Welcome to MSDN Blogs Sign in | Join | Help
Replacing Developers with Perl Scripts

It’s important that as a new developer you do not succumb to a mind numbing repetitive task.

One, you’ll look like an idiot when someone else does the same thing with a script or a tool but in 1/100th the time.

Two, you could have tons of time to slack off if you’d only used the tools at hand!

Things that are very handy that you should know:

Regular Expressions – Find and replace complex patterns of text. Many IDE’s, such as Visual Studio have an implementation you can use.

A scripting language, such as Perl – Take some kind of input, process it (using regular expressions), spit something out.

Excel – Generate number sequences from formulas and sorting data.

These things have saved me countless hours. I had to generate a templated class with a bunch of repeated typenames from T1 through T120. I wrote a quick Perl script to do my bidding for me:

            $i = 120
    
printf( "   template< " );
     for( $j = 1; $j <= $i; $j++ )
     {
           printf( "typename T%d", $j);
           if( $j != $i )
           {
                printf( ", " );
           }
     }
     printf( ">\n");

What’s great about regular expressions and scripts is that if it turns out you have to change the formatting or the number of values you want to write out, it’s a simple change.

Plus it’s fun to write throw away code that only has to work once.

An Intern Story

When I worked as an intern for a nameless blue company, another intern was given the [fun] task of porting a database to a newer version. The work came down to taking this huge definition text file and making it work with the new system.

The changes were mainly comments now used slashes instead of apostrophes and some keyword differences.

For two days he chugged along hitting backspace and / repeatedly.

When I had finished my project, I was asked to help him. I copied the entire file into Word, did a couple of find/replaces and was done.

“Chris, the savior of the database!” they cheered [in my head].

Of course, now neither of us had anything to do for the rest of the week.

A Microsoft Story

We have some code which gets auto-generated based on some input data files. If you add new data, but don’t update certain helper headers, you’ll get a list of linker errors like the following:

            Unresolved external GenClass1::s_id in gen.obj
     Unresolved external GenClass24::s_id in gen.obj
     Unresolved external TempClass1::s_id in gen.obj
     Unresolved external GenClass8::s_id in gen.obj
     Unresolved external GenStruct4::s_id in gen.obj

     ... (600 more lines)


So we have a handy dandy macro which will define the IDs for these classes:

 DEFINE_ID( GenClass );

I could have spent all day copying and pasting the class names in. Or I could load the error output into Visual Studio and use its great find and replace tool which allows for regular expressions:

                Find   .*external    and replace with     DEFINED\_ID\(

                Find    \:\:s_id.*     and replace with     \)\;

The result:

     DEFINE_ID( GenClass1 );
     DEFINE_ID( GenClass24 );
     DEFINE_ID( TempClass1 );
     DEFINE_ID( GenClass8 );
     DEFINE_ID( GenStruct4 );
     ... (600 more lines of code
          I didn't have to write)

Tada!   [........It’s the final countdown…]

Posted: Monday, February 11, 2008 10:58 PM by Chris Becker
Filed under:

Comments

Jordan Sissel said:

120 template parameters? Sounds terrifying.

# February 13, 2008 5:05 PM

petdance said:

Excellent!  I love when people take advantage of higher level languages in just the way you show.

One of the beauties of Perl and other dynamic languages is that they abstract away much of the drudgery for you.

For example, your

 printf( "typename T%d", $j);

could be

 print "typename T$j";

The interpolation and numeric-to-string conversion just happens on its own.  In fact, we can easily create a list of those typenames like so:

 my @types = map { "typename T$_" } 1..120;

The comma dance of "Am I on the first comma?" goes away with the join() function, like so:

 print 'template < ', join( ', ', @types ), ">\n";

So in all, those two lines of Perl:

 my @types = map { "typename T$_" } 1..120;

 print 'template < ', join( ', ', @types ), ">\n";

replace all the C code above, and let you think about what you want to do (create a list of types, and then print them strung together with commas) and less about how it's going to happen.

# February 15, 2008 1:56 PM

Chris Becker said:

Ha, that's pretty sweet! To be honest, I coded the above as C code first, then realized I'd forgotten the $ in front of my variables.

There are some advantanges to leaving it as I had it, mainly it's easier for me to interpret C like code than the two lines you wrote there.

Of course, if I was a total perl guru, I likely could have shaved 30 more seconds off the time it took me to make the script.

Jordan:

But templates are totally awesome! I will give you though that this is a bit of an extreme case. It's an extension to a mechanism that wasn't really meant to handle this many different types. But it's either continue to use it or invent something new and replace all the code that uses the current method.

# February 15, 2008 2:41 PM

petdance said:

Sure, you start with what you know, and keep adding features.  Perl's regular expression facility is without peer.  Your unresolved externals is simple for Perl, too:

 perl -p -e's/Unresolved external (.+)::.*/DEFINE_ID( $1 );/' list-of-errors.txt

So many fun things to do with your power tools! :-)

# February 16, 2008 1:02 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Page view tracker