Perl/Hello World

From Wikiversity
Jump to navigation Jump to search

In this tutorial, we are going to develop a simple 'Hello world' perl script with some nice features.

Prerequisites[edit]

You need a minimal understanding of the Perl programming language.

Note: While these scripts should run on Windows without modification (either Cygwin or ActiveState Perl), they are only tested on unix.

Classic version[edit]

Here's the classic version of 'Hello World':

Code[edit]

#!/usr/bin/perl

print "Hello, World!\n";

Discussion[edit]

This just prints the string "Hello, World!" plus a line-feed.

Ascii-Art version[edit]

For the Ascii-Art version, put the following text into a file called hello.txt (or draw your own):

 _   _      _ _        __        __         _     _
| | | | ___| | | ___   \ \      / /__  _ __| | __| |
| |_| |/ _ \ | |/ _ \   \ \ /\ / / _ \| '__| |/ _` |
|  _  |  __/ | | (_) |   \ V  V / (_) | |  | | (_| |
|_| |_|\___|_|_|\___/     \_/\_/ \___/|_|  |_|\__,_|

We are going to read the file and output it on a line-by-line basis; more or less like the unix command 'cat' or the DOS command 'type'.

Code[edit]

#!/usr/bin/perl

use strict;
use warnings;

open(my $fh, "hello.txt") or die("Can't open hello.txt");

while(my $line = <$fh>) {
    print $line;
}
close $fh;

Discussion[edit]

The first commands use strict; and use warnings; force us to declare all variables as my or our before using them and also help us identify other problems by either warning us or refusing to start the program altogether.

This is good, because it helps you to find problems very early on and also helps avoiding some obscure logic bugs like typing errors in variable names.

The command open(my $fh, "hello.txt") or die("Can't open hello.txt"); opens a read-only filehandle we call '$fh' to a file called "hello.txt". If the open-command fails, we stop the program ('die') with an appropriate error message.

As you can see, the commands 'open' and 'die' are connected with an or command. That means, it will try to successfully run 'open' or 'die', starting with 'open'. That way, when we can't open the file, 'open' returns 'undef'; which for or is the same as 'false'. In that case, perl runs 'die'. If, on the other hand, open succeeds, it returns a filehandle (which of course is 'true'), and or doesn't have to run the 'die' command.

The next construct is our main loop. Most of the work is done by while(my $line = <$fh>): For every iteration of the loop, we declare a local variable '$line' with my. At the same time, we initialize it with data from our filehandle '$fh'.

Because '$line' is a scalar variable (e.g. holds only one single value), we only read one single line from the file. With the next command print $line; we output this line.

After finishing the loop (e.g. no more lines to read, '$line' gets 'undef', 'while' interprets that as 'false'), we close the file with close $fh; to free the file's resources.

Shorter Ascii-Art version[edit]

Now, we got a working prototype, let's shorten to code somewhat, to see how implicit variables work.

Code[edit]

#!/usr/bin/perl

use strict;
use warnings;

open(my $fh, "hello.txt") or die("Can't open hello.txt");
    
while(<$fh>) {
    print;
}
## or,

print while(<$fh>);
close $fh;

Discussion[edit]

The difference in this version is the main loop. More or less, we just leave out using our variable '$line'. As both the 'while' and 'print' command need a variable to work with - but we haven't given them one - they automatically use perl's built-in standard scalar variable called '$_'.

Note: While there are only a few uses where you'd actually need that behavior, it makes the code quite unreadable. Nevertheless, sooner or later you'll come across some program actually using this feature.

Super-short Ascii-Art version[edit]

Here's a really short version of the above program.

Code[edit]

#!/usr/bin/perl
open($h,"hello.txt")or die$!;
print while(<$h>);
close$h;

Discussion[edit]

This version leaves out most non-essential things including even basic code formatting.

First of all, we leave out all pragmas. So we don't get any advanced warnings (which is a bad thing). On the good side, we don't have to use 'our' or 'my' and so can save even more code.

In the open/die construct, we use perls built-in error variable '$!' instead of our own error message. Works quite well, actually. The main loop stays essentially the same, we just leave out some linebreaks.

Final advice[edit]

While the shortened code examples show all the "unneeded" things, they are not fit for production use! They may be ok for quick testing, but thats it.

Special advise from Cavac: Even when writing just a quick test or a proof-of-concept, always use 'strict' and 'warnings'; otherwise even a simple typo in a ten-liner might make you pull your hairs for hours.