Main Content

Different perl examples - some corners I rarely explore

Archive - Originally posted on "The Horse's Mouth" - 2010-07-18 23:39:40 - Graham Ellis

The private Perl course that I ran on Wednesday through Friday of last week was a little out of the ordinary as we were concentrating far more that usual on a wide variety of practices that may be found - either in legacy code or advanced recent code. Great fun for me, and plenty of new examples.

Here are some notes (part 1 or 2) which I wrote up for the delegates - if something in the summary notes has attracted your attention to this page, follow the program name link just above it, and you'll find the full source code I am talking about.

about albert in module P224
about victoria in module P224

1. Set up a SIMPLE signal handler under signals. Nothing complex as this happened asynchronously and there's a danger of actions at the wrong moment - far better to set a flag and process at a specified time in the main program loop

2. Two ^C presses in 3 seconds cause the code to exit; a single ^C just gives a message

3. You can fork a process to give a parent and child, each of which goes off to do its own thing. Fork returns "0" to the child, and the pid of the new process to the child - that's how you tell them apart and have them each go their on way

4. Processes can talk to each other through a pipe; open the pipe before you fork, and when you fork you end up with two pipes - the write handle on each process sending to the read handle on the other. Processes can be told to read from each other via a signal (not illustrated in this example)

about assume in module P203

Perl assues that variables start with an empty string, which when used in a numeric context gets converted into a zero.

It is doubtful if it is good practise to make use of this default initialization, and if you run perl with the -w option you'll get a warning message to let you know about the potential problem

about biggest in module P602

Opendir, readdir and closedir are the recommended way of going through a lot of files on the file system - they don't start a fresh shell and they don't waste time sorting the entries into order. So they run quickly and are not operating system dependent.

You'll get back all file names and directory names - including "." (the current directory) and .. (the parent) and if you're descending into child directories, you must eliminate these!

about bip in module P206
about tae in module P206

There are multiple ways of doing most things in Perl - this example shows five different ways of writing an "if" (and it doesn't even start with the unless conditionals!), and four different forms of comparator - eq == =~ and ~~.

The do ... while loop is a great way to check user input and to reprompt as often as necessary to get a valid response. Ideally, wrap it in a sub ...

about cafe3 in module P218
about dish.pm in module P218
about cafe in module P218

The Exporter module supplied with Perl lets you offer variables that are within your package in the parent namespace too. i.e. it lets you refer to them by simple names such as $n_dishes rather than (in my example) $dish::ndishes.

When your use has no parameters, you'll import automatically everything in the @EXPORT list. Empty parameter brackets specify there are to be no imports at all, and brackets with specified names call up those names - which must have been listed within the class in @EXPORT or @EXPORT_OK lists.

about chopin in module P202

Don't get caught by
  print (chop($line));
which will alter $line and just print a new line, or
  print (chomp($line));
which will alter $new line and print out the value "1" or "0".

If you want to print out $line with the new line removed, do the chop or chomp in a separate line before the print!

about ctx in module P208

If you refer to a list in your Perl program, it will work with the whole list. But if you refer to it where only a scalar makes any senses, it will assume you mean the length of the list ... and if you refer to a list within double quotes, all the elements will be joined with a space between them.

There's an example of the various formats in this example, and it also shows how you can refer to individual list elements, the index number of the last element (one less than the number of elements in the list!) and list slices. Finally, it shows you how you can split a line of text into pieces and then name each of the pieces in a scalar al in one line!

about dadu in module P219

A demonstration of the Data::Dumper module supplied with Perl which lets you prin out the contents of a data structure (actually, the Dumper method returns a string so that you can be much more flexible!)

I've also added a $debug variable in my demo which you can comment out to remove tracing from your program - a useful trick in code that needs testing and analysis from time to time, under the programmer's control.


about delay in module P210
about johnny.vegas in module P210
about kbcheck in module P305

Perl's built in select function, without arguments, tells you where the default output from print is currently directed. With a file handle as an argument, it sets that default output to the specified handle.

With multiple parameters, select lets you check whether input is waiting on any input channel, and whether an output channel is open and available. This uses bit masked parameters and vec - so it's an "interesting" piece of code - but very useful if you need to do background work while waiting for the user to answer a question. See also fork and signal ;-)

about dend in module P215

If you add data to a Perl program after the __END__ marker, you can read it from the DATA file handle using at run time. DATA is open and available to you when you run your program, as are STDIN, STDOUT and STDERR. Other file handles must be opened.

about dotty in module P215

If you read from a file handle that contains * or ? characters, Perl assumes that you mean to return file names that match the pattern given. So
  while () {
will report on all files with a "." in their name (remember this is not regular expressions - it's file name globbing!)

about evx in module P303

If you run code in an "eval", and it hits a condition which would normally cause perl program to halt with an error, you'll get back the error message in $@ and the calling code will continue to run. In effect, this is exception handling - try and catch - in Perl.

If you pass a block to eval using { ... }, the block wil be compiled with the main program. But if you pass the block in using " ... ", the block will be compiled just prior to each execution - more flexible, but slower!

about file in module P215

Operations such as -e to check if a file exists usually run on a named file, passed in as a string. But there are two special cases:

1. If you do not specify any parameter, the file who's name is the current contents of the $_ variable will be used

2. If you specify _ (no $ in front of it), then Perl will simply return you more information about the last file you asked about. This is useful and efficient - internally, the operators like -e and -s return a full stat report which is buffered in case you want to ask more about the same file!

about funcall in module P209

=> can be used to replace , in the definition of a hash - it's useful as it helps you tell the keys and values apart, and it allows you to drop the quotes of the key if the key is a bare word with no other meaning in that context and scope.

But you can go further - you can use the => in a sub call in place of a comma, and it gives the effect of named parameters. It's common practise for module authors to collect parameters in this way, and also to accept the bare words with a leading minus sign, so that the issue of them having another meaning in this scope goes away.

This example shows the minus sign and =>in use in the calling of a sub, and also an example of how the sub would be written.

about gawd in module P301

A Perl variable name starting with "*" is a typeglob - that's one each of a sclar, list, hash and file handle. They're used / useful in handline (in effect) lists of file handles through soft references.

Note that a typeglob is in fact a reference - so if you assign a typeglob and then change the data via the original name, you're also changing the data pointed to by the new name.

about goflavours in module P303
about gogo in module P303
about pmg in module P303

Perl has a goto statement (3 flavours actually), and you can also use the last command to jump out of a block, which some people also consider to be a form of the goto statement.

As well as giving a label to the goto statement, you may give a variable of expressing, and Perl will jump to the label named in that string.

Finally, if you pass a named piece of code (a sub) to Perl's goto, it will jump to that sub and fix its stack so that it look like the original was never called.

Only the final type - the "magic goto" - should really be used these days, and that for the specific case of the dynamic loading of code. Bring in code through a require, then goto it!