Skip to main content.
home | support | download

Back to List Archive

Re: Getting older .cgi scripts to work with

From: Bill Moseley <moseley(at)>
Date: Wed Jun 05 2002 - 22:50:10 GMT
At 12:45 PM 06/05/02 -0700, Andrew Lord wrote:
>I have since spent many more hours doing 'perl tutes' and I think I
understand much of what you've done in 
>makewordlist().  But so that I can better understand the script, I wondered 
>if you'd mind explaining some facets for me:

Sure, but much of this is not really swish-e related.

>1. what is "@_"     ?

That has two meanings.  First, it's what you say when you bang you toe in
the middle of the night.  Second it's an array (all arrays in Perl start
with "@") that is available to a subroutine and contains the list of

    foo( "hello", 23, $date );

sub foo {

   my ( $string, $number, $date ) = @_;  

>2. what does "|" do in "open ($fh, "$swish -k $letter|" ) or"   ?

It's a pipe.  Normally you would open() a file for reading or writing.
This is opening a program for reading.  With the pipe at the end it says
run the program "$swish -k $letter" and redirect its output into this
program.  Its "file handle" is the variable $fh and to read the output from
swish you read from the file handle $fh.

>3. Is "gensym;" some sort of perl-predefined operator  ?  

No, above I say "use Symbol;".  Type "perldoc Symbol" to learn about it.
It's common in perl to say:

   open (FH, "somefile.txt");

but "FH" is a global symbol (global to the current package).    What if
some other function also uses "FH"?  Then you have a mess of two functions
using the same variable.

I like to localize every thing I can, so you can do 

use Symbol;
sub read_file {
   my ( $file ) = @_;
   my $file_handle = gensym;
   open ( $file_handle, "<$file" ) or die "Can't open file $file. Error: $!";

   return <$file_handle>;

Since $file_handle is local (due to the "my) to that function when the
function exits that memory is freed, and also an implicit close is done on
that file.  Well, it's better to use the close() function and check its
return value.

>4. what role does "[1]" serve in "if ( my $words = ( split /\s*:\s*/ )[1]

Ok, here's an array:

   @foo = ('apples', 'oranges', 'grapes');

   $type = $foo[1];

$type now contains "oranges".  Likewise, spilt returns an array.  So

   $words = ( split /\s*:\s*/ )[1]

just says return the second element of that array.  perldoc -f split for
more info.  Split uses the scalar variable "$_" by default.  So it's doing

   $string = 'index.swihs-e: hello there Andrew';
   $words = ( split /\s*:\s*/, $string )[1]

$words now contains "hello there Andrew"

can be done like this:

   $_ = 'index.swihs-e: hello there Andrew';
   $words = ( split /\s*:\s*/)[1]

>I've not been able to complete debugging the various sub routines (employing 
>"use strict"). This seems to be because it's not always as simple as putting 
>a "my" in front of the word in question.  Please excuse my lack of knowledge 
>in this area, but are there other equivalent words to "my" that should be 
>used in contexts such as those below (subroutines from dictionary.cgi saved 
>as bm1.cgi & bm2.cgi)? 

Well, it helps to break the program into small chunks, and make each chunk
into it's own subroutine.  And then say to yourself that the subroutine can
only use data passed in on the @_ array parameter list, and can only return
something via a "return" statement.  That is, no side effects allowed.


>"Global symbol %input requires explicit package name at 

>#!/usr/bin/perl -w     
>use strict;	
>my $searchscript = 'simple2sdev.cgi';
>my $swishtags = "index=$input{index}&results=0&search_tags=H&search=";

You are using $input{index} before that hash is defined.

>I have been able to run sub makewordlist() as a separate file, as you 
>suggested.  A good and useful approach.  The script works without a hitch 
>from the command line where it does an excellent printout of words for the 
>default or query letter from an index.swish-e located in the same directory 
>as the script.  However, when makewordlist() is transplanted into 
>dictionary.cgi, and dictionary.cgi is then run in the browser, it doesn't 
>seem to matter which index is selected from the drop-down menu or which 
>letter button is clicked; the script only ever reports the list of words 
>corresponding to the default letter, but only with respect to the content of 
>an index located in the same directory in which the script resides.  
>Nevertheless, the words are correctly hyperlinked.  

Sorry, that's my use of "shift"

It's hard, as I'd completely rewrite the script, but I understand you are
just trying to make it work.

>use Symbol;					###
>						###
>my @stuff = makewordlist( shift || 'b',		### 

You need to replace that "shift || 'b'" with something else.  You need to
pass in the letter to use to select the words.

In short, it looks like the original code had:

 $pattern = $input{'l'}

So, you would probably want something like:

  my @stuff = makewordlist(  $input{'l'} );

Bill Moseley
Received on Wed Jun 5 22:53:49 2002