Did you ever notice how Perl gives you that feeling that you can solve any programming task?

I know it does for me; more than any other programming language.   There may be obstacles, but when Perl is the tool, there's ALWAYS a solution to be found, even if the first 2 or 3 don't succeed.

This weekend, my friend described a work assignment his manager had given him.  He was supposed to produce a demo, where any time an RFID card came into range, it could be detected by an antenna plugged into his laptop.

There was a catch.  It relied on a C program to read the COM1 port, and the software dated back to 1999, and would no longer compile with a recent version of Borland (the libraries were not backwards compatible).  So even though the executable would work, and the source code was there to peruse, he couldn't modify the C program.

He needed to get it done over the weekend, since the boss wanted to have the demo presentable on Monday.

And although the C program seemed to work fine writing to STDOUT, all attempts to write to a logfile and detect the RFID card by reading that logfile had failed.  Now STDERR was also being written too as well, so even though it was a single '.' to STDERR at a time, my friend assured me he only needed to detect that the card was in range, not identify it.  So reading STDERR was another option.

At Perlmonks, of course, we often refer to this problem as "Suffering from Buffering".

Now as I said, if I can use Perl, my instinct tells me the problem will be solvable, no matter what the obstacles.  I offered to take a shot at it, and my friend said it'd be fine to install Perl on his laptop.

Ten minutes or so later, Perl was installed, as was gvim.

Windows-based programming is not my forte (I much prefer Linux), so I wasn't sure whether Windows would buffer the program's output it I tried to create a pipe from it, and read the tail end.  But writing a little test program is quick, and after a minute or two, we knew that it wouldn't work.

"Not a problem", I thought, "I'll just go get the Expect module from CPAN and good-ol' pseudo-terminals will help me force the output to be line-buffered, the way I want it.  Unfortunately, the "cl" compiler wasn't installed, so relying on modules to solve the problem was out.

Next, I tried redirecting STDERR, but the semantics of doing that in Windows thwarted me, so I put that approach aside as well.

Then, while reading through some Windows-specific documentation, I came across a paragraph about reading the COM port in the ActivePerl-Winfaq8:

How do I read from and write to serial ports? Serial ports can be opened just like files in ActivePerl. To open COM1, just do this: open( PORT, "+>COM1" ) or die "Can't open COM1: $!"; You should be able to read from and write to the file handle using the standard I/O functions (read() and print()), but not the system functions (sysread() and syswrite()).

I asked my friend if we could discard the C program altogether, just reading from the COM port ourselves, and he said "Sure!" -- so the next try resulted in opening the COM1 port as described in the documentation. It wasn't immediately successful, but then he remembered something about needing to initialize the COM port by writing a backslash '\' to it, so after doing that, success!  The program started getting COM1 output each time the card was in range!

To be sure the Perl program could now write data to a logfile (unbuffered, of course), and read it from another process at the same time, we inserted a fork in the program, and called another simple Perl script to announce lines as soon as they appeared in the logfile.   This program would keep track of the offset of the logfile each time it read a line, so as to skip lines it had already processed.

My friend was very happy; the whole solution was done in about an hour, and he confessed that he'd been expecting to spend two full days on it using C++.  Instead of using an out-of-date hundreds-of-lines-long C program which we couldn't even change, we did it with about a dozen lines of Perl.  We can still figure out later how to exactly interpret the COM port results, to give the exact RFID information, either by decoding the output bytes, or by visually inspecting the C program sourcecode.

There was never a sense of "this is impossible", only "here's another roadblock, but there's GOT to be a way to do it with Perl!"


Replies are listed 'Best First'.
Re: Empowered by Perl
by CountZero (Bishop) on Oct 15, 2007 at 05:46 UTC
    ++! and an inspiration to us all.

    Really someone should make a logo Empowered by Perl to we can use that in all our little scripts we hand out to solve the world's problems, so people are aware of where the real power lies.

    Of course, the logo should be useable on a CLI. Any ASCII graphics talents around?


    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: Empowered by Perl
by FunkyMonk (Chancellor) on Oct 15, 2007 at 08:37 UTC
    A few years ago, a time when I did consider using different languages for different tasks, I would always end up saying Just Do It In Perl to myself.

    The thought of doing any task in a language other than Perl just doesn't occur to me now.

    The frightening thing is, since coming to the Monastery, I've come to realise how much Perl I still have to learn.


Re: Empowered by Perl
by schumi (Hermit) on Oct 15, 2007 at 08:13 UTC
    ++ indeed! Actually, I know the feeling. Several friends and I have a saying, which comes up whenever we have a task that needs to be done: "Hmm, we should write a Perl script for that..."

    And as you say, there is never a sense impossibility, just a sense of challenge - evene if that sometime is just a challenge of making the script as small as possible.


    There are nights when the wolves are silent and only the moon howls. - George Carlin

Re: Empowered by Perl
by LighthouseJ (Sexton) on Oct 15, 2007 at 12:10 UTC
    I find myself writing a lot of scripts these last few weeks for work. I use sh scripting for little things like "ps | awk" but I find myself going to perl when there's any substantial level of complexity.

    I have found perl a little lacking in two operations though which has turned me back to shell a few times.
    1. I want to just open a file and dump it's contents like my @contents = contents "/my/text/file"; without an 'open' in a regular script (aka not in a one-liner). my @text = grep /important/, contents "/my/text/file" would be very convenient for me. It gets to be a hassle to juggle open's in some circumstances I run across.
    2. I also want to change Perl's IRS which has been a hinderance for a while. I have made my own scripts which fix up the algorithm but I'm surprised Perl hasn't made it easier and more straight-forward.
    "The three principal virtues of a programmer are Laziness, Impatience, and Hubris. See the Camel Book for why." -- `man perl`
      Doesn't seem pretty, but you don't have to deal with closing or colliding with the filehandle...
      my @contents = do { open(my $fh, "/my/text/file") or die; <$fh> };
      tye recommended something like this, some time ago.
      my @contents = do { local *ARGV; @ARGV=('/my/text/file'); <> };
      His also supports concatenation of multiple files, just add them in the parentheses.

      [ e d @ h a l l e y . c c ]

      You can easily put together a module to provide the contents function you describe. Or you could install File::Slurp, which provides several useful variants.

      TGI says moo

        I often find myself only having the barebones stock Solaris installation. Installing a Perl Module is out of the question. Putting a function together might be too involved. The algorithms I've put together seem to work okay though so I guess it'll just be wishful thinking for the time being.
        "The three principal virtues of a programmer are Laziness, Impatience, and Hubris. See the Camel Book for why." -- `man perl`
      There are the ways halley mentions (Re^2: Empowered by Perl) that are not at all involved. There are many other ways as well. I'm offering some of those others, but it's still not an exhaustive list of ways to do this.

      If you're not tied to your syntax, try option 0. If you are, try option 1 or option 2. Note the localization of @ARGV, which is important if you need to specify the content file in the program and still need your command-line arguments. Option 1 always returns a list, so you get a count of lines in scalar context. Option 2 returns whatever the diamond operator read depending on the sub's context. It can be used to read all lines in list context or one line at a time, iteratively, in scalar context.

      If you don't need to specify the file you need the contents from in the program and don't care about mangling @ARGV for other uses you can use option 3, which is what automatic @ARGV handling by <> is for. Note that will do the same for as many files as specified in @ARGV and will implicitly shift them off the array.

      Option 4 is reminiscent of both Option 0 and options 1/2. It lets you specify a single filename on the command line so you don't have your global @ARGV messed with, but it doesn't use a sub.

      Update: Following the same thinking as 0 through 4, option 5 is left for an exercise: Take a command-line argument and pass it to the subroutine from Option 1 or Option 2.

      Option 0:

      Option 1:

      Option 2:

      Option 3:

      Option 4:

      Another approach is to just return what you actually want if you're not looking for all the contents anyway:

      #!usr/bin/perl use warnings; use strict; sub grepfile { local @ARGV = ( $_[1] ); return grep /$_[0]/, <>; } my @text = grepfile 'important', './grepfile'; print @text, "\n"; print @ARGV, "\n";

      Of course, this is not the prettiest Perl code out there. People might complain that you're messing with your tools in ways other than intended. Others would counter, though, that that's what happens with powerful, successful software.

Re: Empowered by Perl
by Popcorn Dave (Abbot) on Oct 15, 2007 at 16:12 UTC
    Fantastic story!

    However, should you have not been around to help your friend, there is a place that you can get free copies of old Borland software free of charge. You may have to do a little digging but I believe that they even go back to Turbo Pascal 1.0.

    Revolution. Today, 3 O'Clock. Meet behind the monkey bars.

    I would love to change the world, but they won't give me the source code

Re: Empowered by Perl
by bradenshep (Beadle) on Oct 15, 2007 at 22:46 UTC
    Very, very ++.

    I tend to think there are three things Perl isn't the best choice for:
    • Operating Systems
    • Real-time Systems
    • Embedded Systems
    And even then, there's nothing strictly preventing Perl from being used in the first and last of these, it just wouldn't be the best choice.

    In fact, I would go a step further to say that the really crucial aspect of Perl is not that everything is possible. That applies even more to C, and to assembler, even in my three above cases. Nothing is impossible in Perl, but the real triumph is that nearly everything is easy and painless in Perl.
    That's what sets it apart from languages such as C, which I might call more powerful, in that they can perform certain tasks Perl cannot, or at least perform them better. Perl's triumph is its expressiveness, the fact that it takes a sometimes shockingly small amount of typing to perform the same task that would take hours and hundreds of lines in another language.
Re: Empowered by Perl
by xiaoyafeng (Deacon) on Oct 17, 2007 at 07:40 UTC
    Perl always is the most powerful weapon in my arsenal. Anytime I encounter obstacle I have to pass, perl would be merged in my brain.

    But I think XS, in other word, perl sometimes has to rely on C compiler is small flaw as mentioned in your story.

    I hope perl will be a omnipotent zeus in nearly future!

    I am trying to improve my English skills, if you see a mistake please feel free to reply or /msg me a correction
Re: Empowered by Perl
by wulvrine (Friar) on Oct 18, 2007 at 18:39 UTC
    100% ++!
    Very inspirational, and very correct. I've often gotten the 'hmm HOW do I do this in Perl', or even 'Did I do this the best way', but never 'CAN it be done'.
    Words to live by friend, keep up the good faith.

    s&&VALKYRIE &&& print $_^q|!4 =+;' *|