Perl


I guess this is more a reminder to myself than useful information, but here goes.

Recently, I read up on PHP 5.x header() function. I ran across this tidbit of info.

HTTP/1.1 requires an absolute URI as argument to ยป Location: including the scheme, hostname and absolute path, but some clients accept relative URIs.

I don’t know about you, but I find RFCs incredibly boring, so I’m glad that some insomniac took the time to find this gem.

Following this standard eliminates another problem in a different language. In Perl, many people correctly use CGI.pm to perform redirects. The CGI manual gives the same advice. Use full URLs to redirect.

Here’s a mini guide to redirection: (Basically, you just print the redirect out.)

(more…)

A common question on the beginner programming mailing lists goes something like this:

have been trying to open a web page into internet explorer using the getprint command and then opening the file for internet explorer. The getprint command only downloads the code to the command window. I have used the following code and have used the getprint line before and after the internet explorer line ,

To the expert this might look similar to “How to apply a phillips head screw with a tire iron?” The obvious answer is “You don’t. You use a screwdriver.”

If you find yourself about to ask a question in this form, you are limiting yourself. Try to look for a solution that does not involve the tire iron. If inspiration doesn’t inspire you, ask the beginner programming group How to do A and leave off the limiting factor B.

In general, subroutines should receive data, process that data, and then output something. There are some exceptions. In void context, we have no output. In the case of information retrieval from a fixed source there may not be any input. An error logging routine might have input and output but no processing.

Good subroutines only affect and are affected by their own environment. If events exterior to the subroutine affect it, you have probably done something wrong. Here's an example of a poorly written subroutine. foo() is using $bar. $bar has not been passed to it. Remember that a well written subroutine has data passed to it. Good subroutines only affect and are affected by their own environment. Deleting the $bar variable outside this subroutine affects the subroutine.

PERL:
  1. sub foo {
  2.     return $bar;
  3. }

(more...)

CGI.pm is a module included in the standard perl distribution. It is the most commonly used module for writing perl scripts that interact with the web.

I run across these mistakes a lot when reviewing beginner perl code. The first mistake has to do with the dual nature of perl modules. A perl module can be accessed either as a function-oriented module or as a object-oriented module or by both methods.

CGI.pm allows both. Under the hood, that makes for some messy looking code. In practice, we find a lot of bloated code. Normally, we would use either the function oriented or the OO version, not both.Here are a few of the most common errors I see.

(more...)

The author of this module chose to use some file scoped variables in a module. This effectively created some global variables used outside the sub. This is not the recommended way to write a subroutine, but I needed an example and this one was handy. :)

PERL:
  1. my $htmltree;
  2. my $node;
  3. my @prevnodes;
  4. my $htmloutput;
  5.  
  6. sub start {
  7.     my $tagname = shift;
  8.     my $attr = shift;
  9.     my $newnode = {};
  10.  
  11.     $newnode->{tag} = $tagname;
  12.     foreach my $key(keys %{$attr}) {
  13.         $newnode->{$key} = $attr->{$key};
  14.     }
  15.     $newnode->{content} = [];
  16.     push @prevnodes, $node;
  17.     push @{$node}, $newnode;
  18.     $node = $newnode->{content};
  19. }

(more...)

Opening files in perl is a fairly easy task. Here are the basic file opens. Do not use them in production code.

PERL:
  1. my $file = 'foo.txt';
  2.  
  3. # open for read
  4. open FH, ">$file";
  5.  
  6. # open for write
  7. open FH, ">$file";
  8.  
  9. # open for append
  10. open FH, ">>$file";

(more...)

There is an old saying amongst carpenters. Measure twice, cut once. This cuts down on materials. The same is true of typing for Perl programmers. Read more, type less. Okay, that doesn't have the same ring, but reading the documentation before writing your script does make sense.

I came across a script recently where a beginner programmer had obviously decided that typing was easier than reading. Here's an excerpt. The author needs to start a really wide table, but won't end it for a while yet.

PERL:
  1. use CGI qw/:standard/;
  2.  
  3. print "<table border = 1>",th,"day",td,"Date",td,"Time In",td,"Break Start",td,"Break End",td,"Time Out",td,"Evening In",td,"Evening Out",td,"flex hours",td,"flex bal",td,"lieu",td,"adjustment",td,"lieu adjustment",td,"type";

(more...)

Many times when writing code, a beginner will ask the language to perform an operation and receive an unusual result. While possible, it is highly unlikely that a beginner will find a bug in perl, JavaScript, etc. Programmers must be humble. The fault ususally lies with us.

Chances are we are asking the programming language to do what we mean instead of telling it what we really want to do. Some languages have logic builin that will try to guess when something might go either way, but we shouldn't depend on this.

Here's an example

PERL:
  1. $time = "10:10:00";
  2. $other_time = "10:10:40";
  3. print $time - $other_time;

No web programming language will return 40 seconds as the answer without extra work.

The programming language does what I want (DWIW), when I was hoping it would do what I mean (DWIM). The next time you don't get a desired result, make certain you are using DWIW.

Sometimes you just have to peek. Whether it's baking brownies, an overheated engine, or a data structure, sometimes you just have to look under the hood. When programming in perl you need to dump the contents of your data structure to see what's there.

PERL:
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5. use Data::Dumper 'Dumper';
  6.  
  7. my @sirsi_array = (
  8.     '671|Psychophysiology|PPSY',
  9.     '671|Psychophysiology|http://www.blackwell-synergy.com/servlet/useragent?func=showIssues&code=psyp',
  10.     '675|Notes and queries|PENG',
  11.     '675|Notes and queries|http://www.bodley.ox.ac.uk/ilej/journals',
  12.     '675|Notes and queries|http://www.ingenta.com/journals/browse/oup/notesj',
  13.     '676|The Journal of general psychology|http://asa.lib.lehigh.edu/cgi-bin/pubid?Pub=14345',
  14.     '681|Greece & Rome|PHIS',
  15.     '681|Greece & Rome|http://www.jstor.org/journals/00173835.html',
  16.     '681|Greece & Rome|http://www3.oup.co.uk/gromej/contents.html',
  17. );
  18.  
  19. my %sirsi;
  20. foreach my $item ( @sirsi_array ) {
  21.     my( $key, $title, $data ) = split /|/, $item;
  22.     push @{ $sirsi{ $key } }, [ $key, $title, ];
  23. }
  24.  
  25. print Dumper \%sirsi;
  26.  
  27. __END__

(more...)

This may seem trivial, but I believe how we organize programs is directly influenced by how we think. Perhaps learning to better organize code will lead to better organized, more efficient thinking.

PERL:
  1. #!/usr/local/bin/perl -w
  2. use strict;
  3. open (FH,"/usr/local/bin/perld/derektapes") or die "cannot open FH: $!\n";
  4. my $w_param="-w ";
  5. my $tick="'";
  6. my $b_param="barcode=";
  7. my $or_string=" or ";
  8. chomp ( my @a = <fh>);
  9.  
  10. #       $a[$i]=$_;
  11. #       $i++;
  12. #       print map {$_, "\n"} @a;
  13.  
  14.         print $w_param$tick;
  15.         while (@a) {
  16.         my @output = ();
  17.                 for ( 1..4 ) {
  18.                         push @output, $b_param . shift @a;
  19.                         last unless @a;
  20.                 }
  21.         print join ($or_string, @output),"\n";
  22.         }
  23. print $tick;

(more...)