Perl
Perl
Perl is a general-purpose programming language originally developed for text manipulation and now used for a wide range of tasks including system administration, web development, network programming, GUI development, and more.
What is PERL?
Perl is a stable, cross platform programming language. Perl stands for Practical Extraction and Report Language. It is used for mission critical projects in the public and private sectors. Perl is Open Source software, licensed under its Artistic License, or the GNU General Public License (GPL). Perl was created by Larry Wall. Perl 1.0 was released to usenet's alt.comp.sources in 1987 PC Magazine named Perl a finalist for its 1998 Technical Excellence Award in the Development Tool category. Perl is listed in the Oxford English Dictionary.
PERL Features
Perl takes the best features from other languages, such as C, awk, sed, sh, and BASIC, among others. Perls database integration interface (DBI) supports third-party databases including Oracle, Sybase, Postgres, MySQL and others. Perl works with HTML, XML, and other mark-up languages. Perl supports Unicode. Perl is Y2K compliant. Perl supports both procedural and object-oriented programming. Perl interfaces with external C/C++ libraries through XS or SWIG. Perl is extensible. There are over 500 third party modules available from the Comprehensive Perl Archive Network (CPAN).
SYNTAX OVERVIEW
A Perl script or program consists of one or more statements. These statements are simply written in the script in a straightforward fashion. There is no need to have a main() function or anything of that kind. Perl statements end in a semi-colon:
# This is a comment
Whitespace is irrelevant:
"Hello, world";
# this would print with a linebreak in the middle print "Hello world";
Double quotes or single quotes may be used around literal strings:
print 42;
You can use parentheses for functions' arguments or omit them according to your personal taste. They are only required occasionally to clarify issues of precedence. Following two statements produce same result.
#!/usr/bin/perl # This will print "Hello, World" on the screen print "Hello, world";
#!/usr/bin is the path where you have installed PERL
$perl hello.pl
This will produce following result:
Hello, World
$perl -v
This will produce following result:
$perl -e 'print 4;\n' RESULT: 4 $perl -e "print 'Hello World!\n";' RESULT: Hello World!
PERL VARRIABLES
print $animal; print "The animal is $animal\n"; print "The square of $answer is ", $answer * $answer, "\n";
There are a number of "magic" scalars with names that look like punctuation or line noise. These special variables are used for all kinds of purposes and they wioll be discussed in Special Variables sections. The only one you need to know about for now is $_ which is the "default variable". It's used as the default argument to a number of functions in Perl, and it's set implicitly by certain looping constructs.
print;
my @animals = ("camel", "llama", "owl"); my @numbers = (23, 42, 69); my @mixed = ("camel", 42, 1.23);
Arrays are zero-indexed but you can change this setting by changing default variable $[ or $ARRAY_BASE. Here's how you get at elements in an array:
The special variable $#array tells you the index of the last element of an array:
print $mixed[$#mixed];
You might be tempted to use $#array + 1 to tell you how many items there are in an array. Don't bother. As it happens, using @array where Perl expects to find a scalar value ("in scalar context") will give you the number of elements in the array:
@animals[0,1]; @animals[0..2];
my @sorted
= sort @animals;
my @backwards = reverse @numbers; # Here sort and reverse are Perl's built-in functions
There are a couple of special arrays too, such as @ARGV (the command line arguments to your script) and @_ (the arguments passed to a subroutine). These are documented in next section "Special Variables".
$fruit_color{"apple"};
# gives "red"
You can get at lists of keys and values with keys() and values() built-in functions.
my $variables = { scalar => { description => "single item", sigil => '$', }, array => { description => "ordered list of items", sigil => '@', }, hash => { description => "key/value pairs", sigil => '%', }, };
Following line will print $
print "$variables->{'scalar'}->{'sigil'}\n"
Variable Context:
PERL treats same variable differently based on Context. For example
my $number = 30;
Here $number is an scalar and contained number in it but when it is called along with a string then it becomes number which is 0, in stead of string:
Escaping Characters:
In PERL we use the backslash (\) character to escape any type of character that might interfere with our code. Below is the example
Case Sensitivity:
Variable names are case sensitive; $foo, $FOO, and $fOo are all separate variables as far as Perl is concerned.
Variable Scoping:
Throughout the previous section all the examples have used the following syntax:
my $var = "value";
The my is actually not required; you could just use:
$var = "value";
However, the above usage will create global variables throughout your program, which is bad programming practice. But my creates lexically scoped variables instead. The variables are scoped to the block (i.e. a bunch of statements surrounded by curly-braces) in which they are defined. Have a look at the following example:
my $a = "foo"; if ($some_condition) { my $b = "bar"; print $a; # prints "foo" print $b; } print $a; print $b; # prints "bar" # prints "foo" # prints nothing; $b has fallen out of scope
Using my in combination with a use strict; at the top of your Perl scripts means that the interpreter will pick up certain common programming errors. For instance, in the example above, the final print $b would cause a compile-time error and prevent you from running the program. Using strict is highly recommended. Following is the usage:
use strict; my $a = "foo"; if ($some_condition) { my $b = "bar"; print $a; # prints "foo" print $b; } print $a; print $b; # prints "bar" # prints "foo" # prints nothing; $b has fallen out of scope
Enclosing blocks, Conditional (if/unless/elsif/else) Loop (for/foreach/while/until/continue) Subroutine eval or do/require/use'd file
If more than one value is listed, the list must be placed in parentheses. All listed elements must be legal lvalues. Scoped--magical built-ins like $/ must currently be localized with local instead.
my my my my my
$foo; # declare $foo lexically local (@wid, %get); # declare list of variables local $foo = "flurp"; # declare $foo lexical, and init it @oof = @bar; # declare @oof lexical, and init it $x : Foo = $y; # similar, with an attribute applied
Lexical scopes of control structures are not bounded precisely by the braces that delimit their controlled blocks; control expressions are part of that scope, too. Thus in the loop the scope of $line extends from its declaration throughout the rest of the loop construct (including the continue clause), but not beyond it.
user_agrees(); } elsif ($answer =~ /^no$/i) { user_disagrees(); } else { chomp $answer; die "'$answer' is neither 'yes' nor 'no'"; }
We encourage the use of lexically scoped variables. Use the following line at the top of your program file to avoid any error. This will remind you to scope the variable using local or mykeyword.
# # # #
dynamically local of variables local dynamic, and init it dynamic, and init it
Because local is a run-time operator, it gets executed each time through a loop. Consequently, it's more efficient to localize your variables outside the loop. If you localize a special variable, you'll be giving a new value to it, but its magic won't go away. That means that all side-effects related to this magic still work with the localized value. This feature allows code like this to work :
# Read the whole contents of FILE in $slurp { local $/ = undef; $slurp = <FILE> ; }
PERL SCALARS
Scalar variables are simple variables containing only one element--a string or a number. Strings may contain any symbol, letter, or number. Numbers may contain exponents, integers, or decimal values. The bottom line here with scalar variables is that they contain only one single piece of data. What you see is what you get with scalar variables.
#!/usr/bin/perl $number = "5"; $exponent = "2 ** 8"; $string = "Hello, PERL!"; $float = 12.39; # We can also assign a scalar an empty (undefined) value: $nothing = undef; # Printing all the above values print "$number\n"; print "$exponent\n"; print "$string\n"; print "$float\n"; print "There is nothing: $nothing\n"; This will give following result 5 2 ** 8 Hello, PERL! 12.39 There is nothing:
Scalar Strings
Strings are scalar as we mentioned previously. There is no limit to the size of the string, any amount of characters, symbols, or words can make up your strings. When defining a string you may use single or double quotations, you may also define them with the q subfunction. Following are examples of how to define strings $single = 'This string $double = "This string $userdefined = q^Carrot is now our quote^; is is single double quoted'; quoted";
\xnn \cX \Q \E
Creates Hexideciamal formatted numbers Control characters, x may be any character Backslash (escape) all following non-alphanumeric characters. Ends \U, \L, or \Q functions
#!/usr/bin/perl $newline = "Welcome to \ntutorialspoint.com!"; $small = "\uthis, Here t will become capital !" $ALLCAPS = "\UThis completely will become capital!"; $PARTIALCAPS = "\UThis half will/E become capital!"; $backslah = "\Q'Hello World'\E!"; print print print print print "$newline\n"; "$small\n"; "$ALLCAPS\n"; "$PARTAILCAPS\n"; "$backslah\n";
This will give following result Welcome to tutorialspoint.com! This, Here t will become capital ! THIS COMPLETELY WILL BECOME CAPITAL! THIS HALF WILL become capital! \'Hello World\'!
#!/usr/bin/perl # Define a string to replace $mystring = "Hello, PERL!"; print "Before replacement : $mystring\n"; substr($mystring, 7) = "World!"; print "After replacement : $mystring\n"; This will give following result Before replacement : Hello, PERL! After replacement : Hello, World!
Because we only specified one numeric parameter for the string, PERL assumed we wanted to replace every character after the 7th, with our new string. If we throw a third parameter in our function we can replace only a chunk of our string with a new string.
#!/usr/bin/perl $mystring = "Hello, PERL!"; print "Before replacement : $mystring\n"; substr($mystring, 3, 6) = "World!"; print "After replacement : $mystring\n"; This will give following result Before replacement : Hello, PERL! After replacement : HelWorld!RL!
Multiline Strings
If you want to introduce multiline strings into your programs, you can use standard quotes:
V-Strings
V-strings can be a useful way of introducing version numbers and IP addresses into Perl. They are any literal that begins with a v and is followed by one or more dot-separated elements. For example: $name = v77.97.114.116.105.110;
Numeric Scalars
Perl supports a number of a fairly basic methods for specifying a numeric literal in decimal:
You can also specify literals in hexadecimal, octal, and binary by specifying a preceding character to highlight the number types:
PERL ARRAYS
An array is just a set of scalars. It's made up of a list of individual scalars that are stored within a single variable. You can refer to each scalar within that list using a numerical index.
Array Creation:
Array variables are prefixed with the @ sign and are populated using either parentheses or the qw operator. For example:
#!/usr/bin/perl @shortdays = qw/Mon Tue Wed Thu Fri Sat Sun/; print $shortdays[1]; This will print Tue
Array indices start at zero, so in the preceding example we.ve actually printed "Tue". You can also give a negative index.in which case you select the element from the end, rather than the beginning, of the array. This means that
$shortdays[0]; # Outputs Mon $shortdays[6]; # Outputs Sun $shortdays[-1]; # Also outputs Sun $shortdays[-7]; # Outputs Mon
#!/usr/bin/perl @10 = (1 .. 10); @100 = (1 .. 100; @1000 = (100 .. 1000); @abc = (a .. z); print print print print "@10"; "@100"; "@1000"; "@abc"; # # # # Prints Prints Prints Prints number number number number starting starting starting starting from from from from 1 1 1 a to to to to 10 100 1000 z
Array Size
The size of an array can be determined using scalar context on the array - the returned value will be the number of elements in the array:
#!/uer/bin/perl @array = (1,2,3); $array[50] = 4; print "Size: ",scalar @array,"\n"; print "Max Index: ", $#array,"\n"; This will return Size: 51 Max Index: 50
There are only four elements in the array that contain information, but the array is 51 elements long, with a highest index of 50. Here scalar function is used to enforce scalar context so that @array can return size of the array otherwise @array will return a lisrt of all the elements contacined in it.
push(): adds an element to the end of an array. unshift(): adds an element to the beginning of an array. pop(): removes the last element of an array. shift() : removes the first element of an array.
When adding elements using push() or shift() you must specify two arguments, first the array name and second the name of the element to add. Removing an element with pop() or shift() only requires that you send the array as an argument.
#!/usr/bin/perl # Define an array @coins = ("Quarter","Dime","Nickel"); print "First Statement : @coins"; print "\n"; # Add one element at the end of the array push(@coins, "Penny"); print "Second Statement : @coins"; print "\n"; # Add one element at the beginning of the array unshift(@coins, "Dollar"); print "Third Statement : @coins"; print "\n"; # Remove one element from the last of the array. pop(@coins); print "Fourth Statement : @coins"; print "\n"; # Remove one element from the beginning of the array. shift(@coins); print "Fifth Statement : @coins"; print "@coins"; Now this will produce following result First Statement : Quarter Dime Nickel Second Statement : Quarter Dime Nickel Penny Third Statement : Dollar Quarter Dime Nickel Penny Fourth Statement : Dollar Quarter Dime Nickel Fifth Statement : Quarter Dime Nickel
@weekdays = @shortdays[0,1,2,3,4];
The specification for a slice must a list of valid indices, either positive or negative, each separated by a comma. For speed, you can also use the .. range operator:
@weekdays = @shortdays[0..4];
Ranges also work in lists:
@weekdays = @shortdays[0..2,6,7];
#!/usr/bin/perl # Define Strings $astring = "Rain-Drops-On-Roses-And-Whiskers-On-Kittens"; $namelist = "Larry,David,Roger,Ken,Michael,Tom"; # Strings are now arrays. Here '-' and ',' works as delimeter @array = split('-',$astring); @names = split(',',$namelist); print $array[3]; print "\n"; print $names[4]; # This will print Roses # This is a new line # This will print Michael
Likewise, we can use the join() function to rejoin the array elements and form one long, scalar string.
#!/usr/bin/perl # Define Strings $astring = "Rain-Drops-On-Roses-And-Whiskers-On-Kittens"; $namelist = "Larry,David,Roger,Ken,Michael,Tom"; # Strings are now arrays. Here '-' and ',' works as delimeter @array = split('-',$astring); @names = split(',',$namelist); $string1 = join(",", @array); $string2 = join("-", @names); print $string1; print "\n" ; print $string2; This will produce following result
Rain,Drops,On,Roses,And,Whiskers,On,Kittens Larry-David-Roger-Ken-Michael-Tom
Sorting Arrays
The sort() function sorts each element of an array according to ASCII Numeric standards.
#!/usr/bin/perl # Define an array @foods = qw(pizza steak chicken burgers); print "Before sorting: @foods\n"; # Sort this array @foods = sort(@foods); print "After sorting: @foods\n"; This will produce following result Before sorting: pizza steak chicken burgers After sorting: burgers chicken pizza steak
Please note that sorting is performed based on ASCII Numeric value of the words. So the best option is to first transform every element of the array into lowercase letters and then perform the sort function.
The Lists
Lists are really a special type of array - .essentially, a list is a temporary construct that holds a series of values. The list can be "hand" generated using parentheses and the comma operator,
@array = (1,2,3);
or it can be the value returned by a function or variable when evaluated in list context:
@numbers = (1,3,(4,5,6));
The embedded list just becomes part of the main list.this also means that we can combine arrays together:
@numbers = (@odd,@even);
Functions that return lists can also be embedded to produce a single, final list:
@numbers = (primes(),squares());
#!/usr/bin/perl $one = (5,4,3,2,1)[4]; print "Value of \$one is $one\n" This will produce follwoing result Value of $one is 1
Similarly, we can extract slices, although without the requirement for a leading @ character:
#!/usr/bin/perl @newlist = (5,4,3,2,1)[1..3]; print "value of new list is @newlist\n"; This will produce follwoing result value of new list is 4 3 2
PERL HASHES
Hashes are an advanced form of array. One of the limitations of an array is that the information contained within it can be difficult to get to. For example, imagine that you have a list of people and their ages.
The hash solves this problem very neatly by allowing us to access that @ages array not by an index, but by a scalar key. For example to use age of different people we can use thier names as key to define a hash.
%ages = ('Martin' => 28, 'Sharon' => 35, 'Rikke' => 29,); print "Rikke is $ages{Rikke} years old\n"; This will produce following result Rikke is 29 years old
Creation of Hash
Hashes are created in one of two ways. In the first, you assign a value to a named key on a one-byone basis:
$ages{Martin} = 28;
In the second case, you use a list, which is converted by taking individual pairs from the list: the first element of the pair is used as the key, and the second, as the value. For example,
Extracting Slices
You can extract slices out of a hash just as you can extract slices from an array. You do, however, need to use the @ prefix because the return value will be a list of corresponding values:
#!/uer/bin/perl %hash = (-Fred => 'Flintstone', -Barney => 'Rubble'); print join("\n",@hash{-Fred,-Barney}); This will produce following result
Flintstone Rubble
Note: Using $hash{-Fred, -Barney} would return nothing.
#!/usr/bin/perl %ages = ('Martin' => 28, 'Sharon' => 35, 'Rikke' => 29); print "The following are in the DB: ",join(', ',values %ages),"\n"; This will produce following result The following are in the DB: 29, 28, 35
These can be useful in loops when you want to print all of the contents of a hash:
#!/usr/bin/perl %ages = ('Martin' => 28, 'Sharon' => 35, 'Rikke' => 29); foreach $key (%ages) { print "$key is $ages{$key} years old\n"; } This will produce following result Rikke is 29 years old 29 is years old Martin is 28 years old 28 is years old Sharon is 35 years old 35 is years old
The problem with this approach is that (%ages) returns a list of values. So to resolve this problem we have each function which will retun us key and value pair as given below
#!/usr/bin/perl %ages = ('Martin' => 28, 'Sharon' => 35, 'Rikke' => 29); while (($key, $value) = each %ages) { print "$key is $ages{$key} years old\n"; } This will produce following result Rikke is 29 years old Martin is 28 years old Sharon is 35 years old
time. You can get around this by using the exists function, which returns true if the named key exists, irrespective of what its value might be:
#!/usr/bin/perl %ages = ('Martin' => 28, 'Sharon' => 35, 'Rikke' => 29); if (exists($ages{"mohammad"})) { print "mohammad if $ages{$name} years old\n"; } else { print "I don't know the age of mohammad\n"; } This will produce following result I don't know the age of mohammad
Sorting/Ordering Hashes
There is no way to simply guarantee that the order in which a list of keys, values, or key/value pairs will always be the same. In fact, it's best not even to rely on the order between two sequential evaluations:
Hash Size
You get the size - that is, the number of elements - from a hash by using scalar context on either keys or values:
#!/usr/bin/perl %ages = ('Martin' => 28, 'Sharon' => 35, 'Rikke' => 29); print "Hash size: ",scalar keys %ages,"\n"; This will produce following result Hash size: 3
#!/usr/bin/perl %ages = ('Martin' => 28, 'Sharon' => 35, 'Rikke' => 29); # Add one more element in the hash $age{'John'} = 40; # Remove one element from the hash delete( $age{'Sharon'} );
SPECIAL VARIABLES
Some variables have a predefined and special meaning in Perl. They are the variables that use punctuation characters after the usual variable indicator ($, @, or %), such as $_ ( explained below ). Most of the special variables have an english like long name eg. Operating System Error variable $! can be written as $OS_ERROR. But if you are going to use english like names then you would have to put one line "use English;" at the top of your program file. This guides the interter to pickup exact meaning of the variable. The most commonly used special variable is $_, which contains the default input and patternsearching string. For example, in the following lines:
#!/usr/bin/perl foreach ('hickory','dickory','doc') { print; print "\n"; } This will produce following result hickory dickory doc
The first time the loop is executed, "hickory" is printed. The second time around, "dickory" is printed, and the third time, "doc" is printed. That's because in each iteration of the loop, the current string is placed in $_, and is used by default by print. Here are the places where Perl will assume $_ even if you don't specify it:
Various unary functions, including functions like ord and int, as well as the all file tests (-f, -d) except for -t, which defaults to STDIN. Various list functions like print and unlink. The pattern-matching operations m//, s///, and tr/// when used without an =~ operator. The default iterator variable in a foreach loop if no other variable is supplied. The implicit iterator variable in the grep and map functions. The default place to put an input record when a line-input operation's result is tested by itself as the sole criterion of a while test (i.e., ). Note that outside of a while test, this will not happen.
Global Scalar Special Variables. Global Array Special Variables. Global Hash Special Variables. Global Special Filehandles. Global Special Constants. Regular Expression Special Variables. Filehandle Special Variables.
The input record separator; newline by default. If set to the null string, it treats blank lines as delimiters.
If used in a numeric context, yields the current value of the errno variable, identifying the last system call error. If used in a string context, yields the $OS_ERROR or corresponding system error string. $ERRNO
The Perl syntax error message from the last eval command.
$EFFECTIVE_USER_ID or $EUID $( $REAL_GROUP_ID or $GID $) $EFFECTIVE_GROUP_ID or $EGID $0 $PROGRAM_NAME $[ The index of the first element in an array and of the first character in a substring. Default is 0. Contains the name of the file containing the Perl script being executed. The effective gid of this process. The real group ID (gid) of this process.
$EXTENDED_OS_ERROR $^F $SYSTEM_FD_MAX $^H Contains internal compiler hints enabled by certain pragmatic modules. The maximum system file descriptor, ordinarily 2.
$^I
The current value of the inplace-edit extension. Use undef to disable inplace
$INPLACE_EDIT editing. $^M The contents of $M can be used as an emergency memory pool in case Perl dies with an out-of-memory error. Use of $M requires a special compilation of Perl. See the INSTALL document for more information. Contains the name of the operating system that the current Perl binary was compiled for.
The internal flag that the debugger clears so that it doesn't debug itself.
The time at which the script began running, in seconds since the epoch.
The name that the Perl binary itself was executed as.
$EXECUTABLE_NAME $ARGV Contains the name of the current file when reading from .
@F
%ENV %SIG
STDERR
The special filehandle for standard input in any package. The special filehandle for standard output in any package. The special filehandle that refers to anything following the __END__ token in the file containing the script. Or, the special filehandle for anything following the __DATA__ token in a required file, as long as you're reading data in the same package __DATA__ was found in. The special filehandle used to cache the information from the last stat, lstat, or file test operator.
_ (underscore)
__FILE__
__LINE__ __PACKAGE__
The string preceding whatever was matched by the last successful pattern match.
The string following whatever was matched by the last successful pattern match.
The last bracket matched by the last search pattern. This is useful if you don't know which of a set of alternative patterns was matched. For $LAST_PAREN_MATCH example: /Version: (.*)|Revision: (.*)/ && ($rev = $+);
$FORMAT_PAGE_NUMBER $= $FORMAT_LINES_PER_PAGE $$FORMAT_LINES_LEFT $~ $FORMAT_NAME $^ The current page length (printable lines) of the currently selected output channel. Default is 60.
The number of lines left on the page of the currently selected output channel.
The name of the current report format for the currently selected output channel. Default is the name of the filehandle.
The name of the current top-of-page format for the currently selected output channel. Default is the name of the filehandle with _TOP $FORMAT_TOP_NAME appended.
PERL IF ELSE.
The conditional statements are if and unless, and they allow you to control the execution of your script. There are five different formats for the if statement:
BLOCK BLOCK else BLOCK BLOCK elsif (EXPR) BLOCK ... BLOCK elsif (EXPR) BLOCK ... else BLOCK if (EXPR)
The first format is classed as a simple statement, since it can be used at the end of another statement without requiring a block, as in:
if ($date == $today)
if ($date == $today) { print "Happy Birthday!\n"; } elsif ($date == $christmas) { print "Happy Christmas!\n"; }
The fifth form allows for both additional tests and a final exception if all the other tests fail:
if ($date == $today) { print "Happy Birthday!\n"; } elsif ($date == $christmas) { print "Happy Christmas!\n"; }else { print "Happy Unbirthday!\n"; }
The unless statement automatically implies the logical opposite of if, so unless the EXPR is true, execute the block. This means that the statement
print "Happy Unbirthday!\n" unless ($date == $today); is equivalent to print "Happy Unbirthday!\n" if ($date != $today);
For example, the following is a less elegant solution to the preceding if...else. Although it achieves the same result, example:
unless ($date != $today) { print "Happy Unbirthday!\n"; } else { print "Happy Birthday!\n"; }
The final conditional statement is actually an operator.the conditional operator. It is synonymous with the if...else conditional statement but is shorter and more compact. The format for the operator is:
PERL LOOPINGS
Perl supports four main loop types: 1. 2. 3. 4. while for until foreach
In each case, the execution of the loop continues until the evaluation of the supplied expression changes.
In the case of a while loop execution continues while the expression evaluates to true. The until loop executes while the loop expression is false and only stops when the expression evaluates to a true value. The list forms of the for and foreach loop are special cases. They continue until the end of the supplied list is reached.
while Loops
The while loop has three forms:
while EXPRLABEL while (EXPR) BLOCKLABEL while (EXPR) BLOCK continue BLOCK
In first form, the expression is evaluated first, and then the statement to which it applies is evaluated. For example, the following line increases the value of $linecount as long as we continue to read lines from a given file: For example, the following line increases the value of $linecount as long as we continue to read lines from a given file:
{ my $i = 0; while ($i <100) { ... } continue { $i++; } } This is equivalent to for (my $i = 0; $i < 100; $i++) { ... }
for Loops
A for loop is basically a while loop with an additional expression used to reevaluate the original conditional expression. The basic format is:
}
You can place multiple variables into the expressions using the standard list operator (the comma):
for(;;) { ... }
until Loops
The inverse of the while loop is the until loop, which evaluates the conditional expression and reiterates over the loop only when the expression returns false. Once the expression returns true, the loop ends. In the case of a do.until loop, the conditional expression is only evaluated at the end of the code block. In an until (EXPR) BLOCK loop, the expression is evaluated before the block executes. Using an until loop, you could rewrite the previous example as:
do { $calc += ($fact*$ivalue); } until $calc >= 100; This is equivalent to do { $calc += ($fact*$ivalue); } while $calc <100;
foreach Loops
The last loop type is the foreach loop, which has a format like this:
LABEL foreach VAR (LIST) BLOCK LABEL foreach VAR (LIST) BLOCK continue BLOCK
Using a for loop, you can iterate through the list using:
an additional variable, $index, to extract the information. Using a foreach loop, you can simplify the process:
Labled Loops
Labels can be applied to any block, but they make the most sense on loops. By giving your loop a name, you allow the loop control keywords to specify which loop their operation should be applied to. The format for a labeled loop is:
OUTER: while(<DATA>) { chomp; @linearray=split; foreach $word (@linearray) { next OUTER if ($word =~ /next/i) } }
goto Statement
There are three basic forms: goto LABEL, goto EXPR, and goto &NAME. In each case, execution is moved from the current location to the destination. In the case of goto LABEL, execution stops at the current point and resumes at the point of the label specified. The goto &NAME statement is more complex. It allows you to replace the currently executing subroutine with a call to the specified subroutine instead.
PERL OPERATORS
There are many Perl operators but here are a few of the most common ones:
Arithmetic Operators
+ * / addition subtraction multiplication division
(Why do we have separate numeric and string comparisons? Because we don't have special variable types, and Perl needs to know whether to sort numerically (where 99 is less than 100) or alphabetically (where 100 comes before 99).
not
(and , or and not aren't just in the above table as descriptions of the operators -- they're also supported as operators in their own right. They're more readable than the C-style operators, but have different precedence to && and friend.
Miscellaneous Operators
= . x .. assignment string concatenation string multiplication range operator (creates a list of numbers)
$a += 1; $a -= 1; $a .= "\n";
left terms and list operators (leftward) left -> nonassoc ++ -right ** right ! ~ \ and unary + and left =~ !~ left * / % x left + - . left << >> nonassoc named unary operators nonassoc < > <= >= lt gt le ge nonassoc == != <=> eq ne cmp left & left | ^ left && left || nonassoc .. ... right ?: right = += -= *= etc. left , => nonassoc list operators (rightward) right not left and left or xor
The basics of handling files are simple: you associate a filehandle with an external entity (usually a file) and then use a variety of operators and functions within Perl to read and update the data stored within the data stream associated with the filehandle. A filehandle is a named internal Perl structure that associates a physical file with a name. All filehandles are capable of read/write access, so you can read from and update any file or device associated with a filehandle. However, when you associate a filehandle, you can specify the mode in which the filehandle is opened. Three basic file handles are - STDIN, STDOUT, and STDERR.
open FILEHANDLE, EXPR open FILEHANDLE sysopen FILEHANDLE, FILENAME, MODE, PERMS sysopen FILEHANDLE, FILENAME, MODE
Here FILEHANDLE is the file handle returned by open function and EXPR is the expression having file name and mode of opening the file. Following is the syntax to open file.txt in read-only mode. Here less than < signe indicates that file has to be opend in read-only mode
open(DATA, "<file.txt");
Here DATA is the file handle which will be used to read the file. Here is the example which will open a file and will print its content over the screen.
Open Function
Following is the syntax to open file.txt in writing mode. Here less than > signe indicates that file has to be opend in writing mode
open(DATA, ">file.txt");
This example actually truncates (empties) the file before opening it for writing, which may not be the desired effect. If you want to open a file for reading and writing, you can put a plus sign before the >
or < characters. For example, to open a file for updating without truncating it:
open(DATA, "+<file.txt");
To truncate the file first:
Entities Definition < or r Read Only Access > or w Creates, Writes, and Truncates >> or a Writes, Appends, and Creates +< or r+ Reads and Writes +> or w+ Reads, Writes, Creates, and Truncates +>> or a+ Reads, Writes, Appends, and Creates
Sysopen Function
The sysopen function is similar to the main open function, except that it uses the systemopen() function, using the parameters supplied to it as the parameters for the system function: For example, to open a file for updating, emulating the +<filename format from open:
The PERMS argument specifies the file permissions for the file specified if it has to be created. By default it takes 0x666 Following is the table which gives possible values of MODE
Value Definition O_RDWR Read and Write O_RDONLY Read Only O_WRONLY Write Only O_CREAT Create the file O_APPEND Append the file O_TRUNC Truncate the file O_EXCL Stops if file already exists O_NONBLOCK Non-Blocking usability
Close Function
To close a filehandle, and therefore disassociate the filehandle from the corresponding file, you use the close function. This flushes the filehandle's buffers and closes the system's file descriptor.
#!/usr/bin/perl print "What is your name?\n"; $name = <STDIN>; print "Hello $name\n";
When you use the <FILEHANDLE> operator in a list context, it returns a list of lines from the specified filehandle. For example, to import all the lines from a file into an array:
getc Function
The getc function returns a single character from the specified FILEHANDLE, or STDIN if none is specified:
read Function
The read function reads a block of information from the buffered filehandle: This function is used to read binary data from the file.
print Function
For all the different methods used for reading information from filehandles, the main function for writing information back is the print function.
Copying Files
Here is the example which opens an existing file file1.txt and read it line by line and generate another copy file2.txt
#!/usr/bin/perl # Open file to read open(DATA1, "<file1.txt"); # Open new file to write open(DATA2, ">file2.txt"); # Copy data from one file to another. while(<DATA1>) { print DATA2 $_;
REGULAR EXPRESSIONS
A regular expression is a string of characters that define the pattern or patterns you are viewing. The syntax of regular expressions in Perl is very similar to what you will find within other regular expression.supporting programs, such as sed, grep, and awk. The basic method for applying a regular expression is to use the pattern binding operators =~ and ! ~. The first operator is a test and assignment operator. There are three regular expression operators within Perl
Match Regular Expression - m// Substitute Regular Expression - s/// Transliterate Regular Expression - tr///
The forward slashes in each case act as delimiters for the regular expression (regex) that you are specifying. If you are comfortable with any other delimiter then you can use in place of forward slash.
if ($bar =~ /foo/)
The m// actually works in the same fashion as the q// operator series.you can use any combination of naturally matching characters to act as delimiters for the expression. For example, m{}, m(), and m>< are all valid. You can omit the m from m// if the delimiters are forward slashes, but for all other delimiters you must use the m prefix. Note that the entire match expression.that is the expression on the left of =~ or !~ and the match operator, returns true (in a scalar context) if the expression matches. Therefore the statement:
Modifier Description i Makes the match case insensitive m Specifies that if the string has newline or carriage return characters, the ^ and $ operators will now match against a newline boundary, instead of a string boundary o Evaluates the expression only once s Allows use of . to match a newline character x Allows you to use white space in the expression for clarity g Globally finds all matches cg Allows the search to continue even after a global match fails
#!/usr/bin/perl @list = qw/food foosball subeo footnote terfoot canic footbrdige/; foreach (@list) { $first = $1 if ?(foo.*)?; $last = $1 if /(foo.*)/; } print "First: $first, Last: $last\n"; This will produce following result First: food, Last: footbrdige
s/PATTERN/REPLACEMENT/;
The PATTERN is the regular expression for the text that we are looking for. The REPLACEMENT is a specification for the text or regular expression that we want to use to replace the found text with. For example, we can replace all occurrences of .dog. with .cat. using
$string =~ s/dog/cat/;
Another example:
#/user/bin/perl $string = 'The cat sat on the mat'; $string =~ s/cat/dog/; print "Final Result is $string\n"; This will produce following result The dog sat on the mat
Modifier Description i Makes the match case insensitive m Specifies that if the string has newline or carriage return characters, the ^ and $ operators will now match against a newline boundary, instead of a string boundary o Evaluates the expression only once s Allows use of . to match a newline character x Allows you to use white space in the expression for clarity g Replaces all occurrences of the found expression with the replacement text e Evaluates the replacement as if it were a Perl statement, and uses its return value as the replacement text
Translation
Translation is similar, but not identical, to the principles of substitution, but unlike substitution, translation (or transliteration) does not use regular expressions for its search on replacement values. The translation operators are:
tr/SEARCHLIST/REPLACEMENTLIST/cds y/SEARCHLIST/REPLACEMENTLIST/cds
The translation replaces all occurrences of the characters in SEARCHLIST with the corresponding characters in REPLACEMENTLIST. For example, using the "The cat sat on the mat." string we have been using in this chapter:
#/user/bin/perl $string = 'The cat sat on the mat'; $string =~ tr/a/o/; print "$string\n"; This will produce following result The cot sot on the mot.
Standard Perl ranges can also be used, allowing you to specify ranges of characters either by letter or numerical value. To change the case of the string, you might use following syntax in place of the uc function.
$string =~ tr/a-z/A-Z/;
Modifier Description c Complement SEARCHLIST. d Delete found but unreplaced characters. s Squash duplicate replaced characters.
The /d modifier deletes the characters matching SEARCHLIST that do not have a corresponding entry in REPLACEMENTLIST. For example:
#!/usr/bin/perl $string = 'the cat sat on the mat.'; $string =~ tr/a-z/b/d; print "$string\n"; This will produce following result b b b.
The last modifier, /s, removes the duplicate sequences of characters that were replaced, so:
#!/usr/bin/perl $string = 'food'; $string = 'food'; $string =~ tr/a-z/a-z/s; print $string; This will produce following result fod
Character . \s \S \d \D \w \W [aeiou]
Description a single character a whitespace character (space, tab, newline) non-whitespace character a digit (0-9) a non-digit a word character (a-z, A-Z, 0-9, _) a non-word character matches a single character in the given set
[^aeiou] (foo|bar|baz)
matches a single character outside the given set matches any of the alternatives specified
Quantifiers can be used to specify how many of the previous thing you want to match on, where "thing" means either a literal character, one of the metacharacters listed above, or a group of characters or metacharacters in parentheses.
Description zero or more of the previous thing one or more of the previous thing zero or one of the previous thing matches exactly 3 of the previous thing matches between 3 and 6 of the previous thing matches 3 or more of the previous thing
The ^ metacharacter matches the beginning of the string and the $ metasymbol matches the end of the string. Here are some brief examples
# nothing in the string (start and end are adjacent) /^$/ # a three digits, each followed by a whitespace # character (eg "3 4 5 ") /(\d\s){3}/ # matches a string in which every # odd-numbered letter is a (eg "abacadaf") /(a.)+/ # string starts with one or more digits /^\d+/ # string that ends with one or more digits /\d+$/
Lets have alook at another example
#!/usr/bin/perl $string = "Cats go Catatonic\nWhen given Catnip"; ($start) = ($string =~ /\A(.*?) /); @lines = $string =~ /^(.*?) /gm; print "First word: $start\n","Line starts: @lines\n"; This will produce following result First word: Cats Line starts: Cats When
Matching Boundaries
The \b matches at any word boundary, as defined by the difference between the \w class and the \W class. Because \w includes the characters for a word, and \W the opposite, this normally
means the termination of a word. The \B assertion matches any position that is not a word boundary. For example:
# # # #
'the cat sat' but not 'cat on the mat' 'verification' but not 'the cat on the mat' 'catatonic' but not 'polecat' 'polecat' but not 'catatonic'
Selecting Alternatives
The | character is just like the standard or bitwise OR within Perl. It specifies alternate matches within a regular expression or group. For example, to match "cat" or "dog" in an expression, you might use this:
if ($string =~ /cat|dog/)
You can group individual elements of an expression together in order to support complex matches. Searching for two people.s names could be achieved with two separate tests, like this:
if (($string =~ /Martin Brown/) || ($string =~ /Sharon Brown/)) This could be written as follows if ($string =~ /(Martin|Sharon) Brown/)
Grouping Matching
From a regular-expression point of view, there is no difference between except, perhaps, that the former is slightly clearer.
When groups are used in substitution expressions, the $x syntax can be used in the replacement text. Thus, we could reformat a date string using this:
#!/usr/bin/perl $date = '03/26/1999'; $date =~ s#(\d+)/(\d+)/(\d+)#$3/$1/$2#; print "$date"; This will produce following result 1999/03/26
#!/usr/bin/perl $string = "The time is: 12:31:02 on 4/12/00"; $string ($time) $string ($date) =~ /:\s+/g; = ($string =~ /\G(\d+:\d+:\d+)/); =~ /.+\s+/g; = ($string =~ m{\G(\d+/\d+/\d+)});
print "Time: $time, Date: $date\n"; This will produce following result Time: 12:31:02, Date: 4/12/00
The \G assertion is actually just the metasymbol equivalent of the pos function, so between regular expression calls you can continue to use pos, and even modify the value of pos (and therefore \G) by using pos as an lvalue subroutine:
#!/usr/bin/perl $string = "The food is in the salad bar"; $string =~ m/foo/; print "Before: $`\n"; print "Matched: $&\n"; print "After: $'\n"; This code prints the following when executed:
PERL SUBROUTINES
The two terms function and subroutine are used interchangeably in Perl. A function is a named code block that is generally intended to process specified input values into an output value, although this is not always the case. For example, the print function takes variables and static text and prints the values on the screen.
Like many languages, Perl provides for user-defined subroutines. These may be located anywhere in the main program. Loaded in from other files via the do, require, or use keywords. Any arguments passed in show up in the array @_. A return statement may be used to exit a subroutine. If no return is found and if the last statement is an expression, its value is returned. If the last statement is a loop control structure like a foreach or a while , the returned value is unspecified. Subroutines can return Scalar, Array or Hash.
Subroutines, like variables, can be declared (without defining what they do) or declared and defined. To simply declare a subroutine, you use one of the following forms:
where NAME is the name of the subroutine you are creating, PROTO is the prototype for the arguments the subroutine should expect when called, and ATTRS is a list of attributes that the subroutine exhibits. If you want to declare and define a function, then you need to include the BLOCK that defines its operation:
You can also create anonymous subroutines - subroutines without a name by omitting the NAME component:
Function Arguments
The first argument you pass to the subroutine is available within the function as $_[0], the second argument is $_[1], and so on. For example, this simple function adds two numbers and prints the result:
sub add { $result = $_[0] + $_[1]; print "The result was: $result\n"; }
To call the subroutine and get a result:
add(1,2);
The preceding subroutine is fairly simple, but what if you wanted to have named arguments? The simple answer is to assign the values of @_ to a list of variables:
sub add { ($numbera, $numberb) = @_; $result = $numbera + $numberb; print "The result was: $result\n"; }
The shift function is one of the .stack. operands supported by Perl. The shift function returns (and removes) the first element of an array. For example:
sub add { my $numbera = shift; my $numberb = shift; my $result = $numbera + $numberb; print "The result was: $result\n"; }
The effect is exactly the same as we have shown earlier but we have just obtained the arguments in a different way.
$name = getpwent(); ($name, $passwd, $uid, $gid, $quota, $comment, %gcos, $dir, $shell) = getpwent();
In the first case, the user expects a scalar value to be returned by the function, because that is what the return value is being assigned to. In the second case, the user expects an array as the return value, again because a list of scalars has been specified for the information to be inserted into. Here's another example, again from the built-in Perl functions, that shows the flexibility:
my $timestr = localtime(time);
In this example, the value of $timestr is now a string made up of the current date and time, for example, Thu Nov 30 15:21:33 2000. Conversely:
Now the individual variables contain the corresponding values returned by localtime.
Lvalue subroutines
WARNING: Lvalue subroutines are still experimental and the implementation may change in future versions of Perl. It is possible to return a modifiable value from a subroutine. To do this, you have to declare the subroutine to return an lvalue. See the following example
my $val; sub canmod : lvalue { # return $val; this doesn't work, don't say "return" $val; } sub nomod { $val; }
Now see the magic
canmod() = 5; nomod() = 5;
sub simplesort {
my ($listaref, $listbref ) = @_; # De-reference the array list my (@lista) = @$listaref; my (@listb) = @$listbref; # Now you can play with both arrays. }
sub display_hash { my (%hash) = @_; foreach (%hash) { print "$_ => $hash{$_}\n"; } }
In this case, we output the key/value pairs of the hash properly, displaying each pair on its own line. As with arrays, care needs to be taken if you expect to pick out a single hash from a list of arguments. The following will work because we extract the hash last:
my %newhash; foreach my $key (keys %{$hasha}) { $newhash{$key} = $$hasha{$key} if (exists $$hashb{$key}); } return %newhash; }
To use the subroutine:
%hasha = ('a' => 'b', 'b' => 'b', 'c' => 'b'); %hashb = ('b' => 'b', 'c' => 'b', 'd' => 'b'); %newhash = intersection(\%hasha, \%hashb);
PERL FORMATS
As stated earlier that Perl stands for Practical Extraction and Reporting Language, and we'll now discuss using Perl to write reports. Perl uses a writing template called a 'format' to output reports. To use the format feature of Perl, you must:
Define a Format Pass the data that will be displayed on the format Invoke the Format
Define a Format
Following is the syntax to define a Perl format
format FormatName = fieldline value_one, value_two, value_three fieldline value_one, value_two . FormatName represents the name of the format. The fieldline is the specific way the data should be
formatted. The values lines represent the values that will be entered into the field line. You end the format with a single period.
fieldline can contain any text or fieldholders. Fieldholders hold space for data that will be placed
there at a later date. A fieldholder has the format:
@<<<<
This fieldholder is left-justified, with a field space of 5. You must count the @ sign and the < signs to know the number of spaces in the field. Other field holders include:
@>>>> right-justified @|||| centered @####.## numeric field holder @* multiline field holder
An example format would be:
format EMPLOYEE = =================================== @<<<<<<<<<<<<<<<<<<<<<< @<< $name $age @#####.## $salary =================================== .
In this example $name would be written as left justify within 22 character spaces and after that age will be written in two spaces.
select(STDOUT);
We would then associate EMPLOYEE with STDOUT by setting the new format name with STDOUT, using the special variable $~
$~ = "EMPLOYEE";
When we now do a write(), the data would be sent to STDOUT. Remember: if you didn't have STDOUT set as your default file handle, you could revert back to the original file handle by assigning the return value of select to a scalar value, and using select along with this scalar variable after the special variable is assigned the format name, to be associated with STDOUT. The above example will generate a report in the following format
Kirsten
12
35 15 10
Page @< $%
Page 1
You can set the number of lines per page using special variable $= ( or $FORMAT_LINES_PER_PAGE ) By default $= will be 60
Page 1
For a complete set of variables related to formating, please refer to Perl Special Variablessection.
You can identify and trap an error in a number of different ways. Its very easy to trap errors in Perl and then handling them properly. Here are few methods which can be used.
Using if
The if statement is the obvious choice when you need to check the return value from a statement; for example:
if (open(DATA,$file)) { ... } else { die "Error: Couldn't open the file $!"; }
Here variable $! returns the actual error message Alternatively, we can reduce the statement to one line in situations where it makes sense to do so; for example:
Using unless
The unless function is the logical opposite to if: statements can completely bypass the success status and only be executed if the expression returns false. For example:
Reporting an error in a module that quotes the module's filename and line number - this is useful when debugging a module, or when you specifically want to raise a module-related, rather than script-related, error.
Reporting an error within a module that quotes the caller's information so that you can debug the line within the script that caused the error. Errors raised in this fashion are useful to the end-user, because they highlight the error in relation to the calling script's origination line.
The warn and die functions work slightly differently than you would expect when called from within a module. For example, the simple module:
package T; require Exporter; @ISA = qw/Exporter/; @EXPORT = qw/function/; use Carp; sub function { warn "Error in module!"; } 1;
when called from a script
use T; function(); It will produce following result Error in module! at T.pm line 11.
This is more or less what you might expect, but not necessarily what you want. From a module programmer's perspective, the information is useful because it helps to point to a bug within the module itself. For an end-user, the information provided is fairly useless, and for all but the hardened programmer, it completely pointless. The solution for such problems is the Carp module, which provides a simplified method for reporting errors within modules that return information about the calling script. The Carp module provides four functions: carp, cluck, croak, and confess. These functions are discussed below
carp "Error in module!"; This would result in Error in module! at test.pl line 3
cluck "Error in module!"; This would result in something like Error in module! at T.pm line 11 T::function() called at S.pm line 13 S::raise() called at test.pl line 3
croak "Definitely didn't work"; This would result in Error in module! at S.pm line 13
As with carp, the same basic rules apply regarding the including of line and file information according to the warn and die functions.
confess "Failed around about there"; This would result in Error in module! at T.pm line 11 T::function() called at S.pm line 13 S::raise() called at t2.pl line 3
Each programmer will, of course, have his or her own preferences in regards to formatting, but there are some general guidelines that will make your programs easier to read, understand, and maintain The most important thing is to run your programs under the -w flag at all times. You may turn it off explicitly for particular portions of code via the no warnings pragma or the $^W variable if you must. You should also always run under use strict or know the reason why not. The use sigtrap and even use diagnostics pragmas may also prove useful. Regarding aesthetics of code lay out, about the only thing Larry cares strongly about is that the closing curly bracket of a multi-line BLOCK should line up with the keyword that started the construct. Beyond that, he has other preferences that aren't so strong:
4-column indent. Opening curly on same line as keyword, if possible, otherwise line up.
Space before the opening curly of a multi-line BLOCK. One-line BLOCK may be put on one line, including curlies. No space before the semicolon. Semicolon omitted in "short" one-line BLOCK. Space around most operators. Space around a "complex" subscript (inside brackets). Blank lines between chunks that do different things. Uncuddled elses. No space between function name and its opening parenthesis. Space after each comma. Long lines broken after an operator (except and and or). Space after last parenthesis matching on current line. Line up corresponding items vertically. Omit redundant punctuation as long as clarity doesn't suffer.
Here are some other more substantive style issues to think about:
Just because you CAN do something a particular way doesn't mean that you SHOULD do it that way. Perl is designed to give you several ways to do anything, so consider picking the most readable one. For instance
Don't go through silly contortions to exit a loop at the top or the bottom, when Perl provides the last operator so you can exit in the middle. Just "outdent" it a little to make it more visible:
LINE: for (;;) { statements; last LINE if $foo; next LINE if /^#/; statements; }
Don't be afraid to use loop labels--they're there to enhance readability as well as to allow multilevel loop breaks. See the previous example. Avoid using grep() (or map()) or `backticks` in a void context, that is, when you just throw away their return values. Those functions all have return values, so use them. Otherwise use a foreach() loop or the system() function instead. For portability, when using features that may not be implemented on every machine, test the construct in an eval to see if it fails. If you know what version or patchlevel a particular feature was implemented, you can test $] ($PERL_VERSION in English) to see if it will be there. The Config module will also let you interrogate values determined by the Configure program when Perl was installed. Choose mnemonic identifiers. If you can't remember what mnemonic means, you've got a problem. While short identifiers like $gotit are probably ok, use underscores to separate words in longer identifiers. It is generally easier to read $var_names_like_this than $VarNamesLikeThis, especially for non-native speakers of English. It's also a simple rule that works consistently with VAR_NAMES_LIKE_THIS. Package names are sometimes an exception to this rule. Perl informally reserves lowercase module names for "pragma" modules like integer and strict. Other modules should begin with a capital letter and use mixed case, but probably without underscores due to limitations in primitive file systems' representations of module names as files that must fit into a few sparse bytes. If you have a really hairy regular expression, use the /x modifier and put in some whitespace to make it look a little less like line noise. Don't use slash as a delimiter when your regexp has slashes or backslashes. Always check the return codes of system calls. Good error messages should go to STDERR, include which program caused the problem, what the failed system call and arguments were, and (VERY IMPORTANT) should contain the standard system error message for what went wrong. Here's a simple but sufficient example:
opendir(D, $dir)
Think about reusability. Why waste brainpower on a one-shot when you might want to do something like it again? Consider generalizing your code. Consider writing a module or object class. Consider making your code run cleanly with use strict and use warnings (or -w) in effect. Consider giving away your code. Consider changing your whole world view. Consider... oh, never mind. Be consistent. Be nice.
NOTE: If you are aware of Unix Sockets then you can leave introduction part
What is a socket?
Just another bit of computer jargon? Going back a little into networking history, it is a Berkeley UNIX mechanism of creating a virtual duplex connection between processes. This was later ported on to every known OS enabling communication between systems across geographical location
running on different OS software. If not for the socket, most of the network communication between systems would never ever have happened. Taking a closer look; a typical computer system on a network receives and sends information as desired by the various applications running on it. This information is routed to the system, since a unique IP address is designated to it. On the system, this information is given to the relevant applications which listen on different ports. For example a net browser listens on port 80 for information. Also we can write applications which listen and send information on a specific port number. For now, let's sum up that a socket is an IP address and a port, enabling connection. To explain the socket we will take an example of Client - Server Programming. To complete a client server architecture we would have to go through the following steps
Creating A Server
Create a socket with socket call. Bind the socket to a port address with bind call. Listen to the socket at the port address with listen call. Accept client connections with accept call.
Creating A Client
Create a socket with socket call. Connect (the socket) to the remote machine with connect call.
Create a socket
The first step in establishing a network connection is creating a socket, with the sockt() function
DOMAIN should be PF_INET. It's probable 2 on your computer. TYPE should be SOCK_STREAM for TCP/IP connection. PROTOCOL should be (getprotobyname('tcp'))[2]. It is the particular protocol such as TCP to be spoken over the socket.
Server uses bind() function to specify the port at which they will be accepting connections from the clients.
As the bind() is used by a server which does not need to know its own address so the argument list looks like this:
$port = 12345; # the port bind( SOCKET, pack( 'Sn4x8', AF_INET, $port, "\0\0\0\0" )) or die "Can't bind to port $port! \n";
The or die clause is very important - if a server dies without outstanding connections the port won't be immediately reusable unless you use the option SO_REUSEADDR using setsockopt()function. Here pack() function is being used to pack all the data into binary format.
Accepting connections
If this is a server program then it is required to issue a call to access() function to accept the incoming connections.
Now all the calls related to server are over and let us see a call which will be required by the client
Connection Establishment
If you are going to prepare client program then after using socket() call you would have to use another call connect() to connect to the server.
$port = 21; # the ftp port $server_ip_address = "10.12.12.168"; connect( SOCKET, pack( 'Sn4x8', AF_INET, $port, $server )) or die "Can't connect to port $port! \n";
If you connect to the server successfully then you can start sending your commands to the server using SOCKET descriptor. So now lets put all the things together
To run the server in background mode issue the following command on Unix prompt
$sever.pl&
$i = 1; print "$i\n"; # Prints "1" package foo; $i = 2; print "$i\n"; # Prints "2" package main; print "$i\n"; # Prints "1"
The package stays in effect until either another package statement is invoked, or until the end of the end of the current block or file. You can explicitly refer to variables within a package using the :: package qualifier
$PACKAGE_NAME::VARIABLE_NAME For Example: $i = 1; print "$i\n"; # Prints "1" package foo; $i = 2; print "$i\n"; # Prints "2" package main; print "$i\n"; # Prints "1" print "$foo::i\n"; # Prints "2"
#!/usr/bin/perl package Foo; sub bar { print "Hello $_[0]\n" } sub blat { print "World $_[0]\n" }
1;
Few noteable points about modules
The functions require and use will load a module. Both use the list of search paths in @INC to find the module (you may modify it!) Both call the eval function to process the code The 1; at the bottom causes eval to evaluate to TRUE (and thus not fail)
@ISA = qw(Exporter); @EXPORT = qw(bar blat); sub bar { print "Hello $_[0]\n" } sub blat { print "World $_[0]\n" } sub splat { print "Not $_[0]\n" } # Not exported! 1;
$h2xs -AX -n
Module Name
# For example, if your module is available in Person.pm file $h2xs -AX -n Person This will produce following result Writing Person/lib/Person.pm Writing Person/Makefile.PL Writing Person/README Writing Person/t/Person.t Writing Person/Changes Writing Person/MANIFEST
Here is the descritpion of these options
-A omits the Autoloader code (best used by modules that define a large number of infrequently used subroutines) -X omits XS elements (eXternal Subroutine, where eXternal means external to Perl, i.e. C) -n specifies the name of the module
So above command creates the following structure inside Person directory. Actual result is shown above.
Changes Makefile.PL MANIFEST (contains the list of all files in the package) README t/ (test files) lib/ ( Actual source code goes here
So finally you tar this directory structure into a file Person.tar and you can ship it. You would have to update README file with the proper instructions. You can provide some test examples files in t directory.
Module.
References
A reference is, exactly as the name suggests, a reference or pointer to another object. There are two types of references: symbolic and hard. A symbolic reference enables you to refer to a variable by name, using the value of another variable. For example, if the variable $foo contains the string "bar", the symbolic reference to $foo refers to the variable $bar. A hard reference refers to the actual data contained in a data structure.
Anonymous Arrays
When you create a reference to an array directly - that is, without creating an intervening named array - you are creating an anonymous array.
Anonymous Hashes
Anonymous hashes are similarly easy to create, except you use braces instead of square brackets:
$hash = { 'Man' => 'Bill', 'Woman' => 'Mary, 'Dog' => 'Ben' };
Dereferencing
The most direct way of dereferencing a reference is to prepend the corresponding data type character ($ for scalars, @ for arrays, % for hashes, and & for subroutines) that you are expecting in front of the scalar variable containing the reference. For example, to dereference a scalar reference $foo, you would access the data as $$foo. Other examples are:
$array = \@ARGV; # Create reference $hash = \%ENV; # Create reference $glob = \*STDOUT; # Create reference $foosub = \&foo; # Create reference push (@$array, "From humans"); $$array[0] = 'Hello' $$hash{'Hello'} = 'World'; &$foosub; print $glob "Hello World!\n";
to to to to
Object Basics
There are three main terms, explained from the point of view of how Perl handles objects. The terms are object, class, and method.
Within Perl, an object is merely a reference to a data type that knows what class it belongs to. The object is stored as a reference in a scalar variable. Because a scalar only contains a reference to the object, the same scalar can hold different objects in different classes. A class within Perl is a package that contains the corresponding methods required to create and manipulate objects. A method within Perl is a subroutine, defined with the package. The first argument to the
method is an object reference or a package name, depending on whether the method affects the current object or the class. Perl provides a bless() function which is used to return a reference and which becomes an object.
Defining a Class
Its very simple to define a class. In Perl, a class is corresponds to a Package.To create a class in Perl, we first build a package. A package is a self-contained unit of user-defined variables and subroutines, which can be re-used over and over again. They provide a separate namespace within a Perl program that keeps subroutines and variables from conflicting with those in other packages. To declare a class named Person in Perl we do:
package Person;
The scope of the package definition extends to the end of the file, or until another package keyword is encountered.
package Person; sub new { my $class = shift; my $self = { _firstName => shift, _lastName => shift, _ssn => shift, }; # Print all the values just for clarification. print "First Name is $self->{_firstName}\n"; print "Last Name is $self->{_lastName}\n"; print "SSN is $self->{_ssn}\n"; bless $self, $class; return $self; }
Every method of a class passes first argument as class name. So in the above example class name would be "Person". You can try this out by printing value of $class. Next rest of the arguments will be rest of the arguments passed to the method.
package Person; sub new { my $class = shift; my $self = {}; bless $self, $class; return $self; }
Defining Methods
Other object-oriented languages have the concept of security of data to prevent a programmer from changing an object data directly and so provide accessor methods to modify object data. Perl does not have private variables but we can still use the concept of helper functions methods and ask programmers to not mess with our object innards. Lets define a helper method to get person first name:
sub setFirstName { my ( $self, $firstName ) = @_; $self->{_firstName} = $firstName if defined($firstName); return $self->{_firstName}; }
Lets have a look into complete example: Keep Person package and helper functions into Person.pm file
#!/usr/bin/perl package Person; sub new { my $class = shift; my $self = { _firstName => shift, _lastName => shift, _ssn => shift, }; # Print all the values just for clarification.
print "First Name is $self->{_firstName}\n"; print "Last Name is $self->{_lastName}\n"; print "SSN is $self->{_ssn}\n"; bless $self, $class; return $self; } sub setFirstName { my ( $self, $firstName ) = @_; $self->{_firstName} = $firstName if defined($firstName); return $self->{_firstName}; } sub getFirstName { my( $self ) = @_; return $self->{_firstName}; } 1;
Now create Person object in mail.pl fileas follows
#!/usr/bin/perl use Person; $object = new Person( "Mohammad", "Saleem", 23234345); # Get first name which is set using constructor. $firstName = $object->getFirstName(); print "Before Setting First Name is : $firstName\n"; # Now Set first name using helper function. $object->setFirstName( "Mohd." ); # Now get first name set by helper function. $firstName = $object->getFirstName(); print "Before Setting First Name is : $firstName\n"; This will produce following result First Name is Mohammad Last Name is Saleem SSN is 23234345 Before Setting First Name is : Mohammad Before Setting First Name is : Mohd.
Inheritance
Object-oriented programming sometimes involves inheritance. Inheritance simply means allowing one class called the Child to inherit methods and attributes from another, called the Parent, so you don't have to write the same code again and again. For example, we can have a class Employee which inherits from Person. This is referred to as an "isa" relationship because an employee is a person. Perl has a special variable, @ISA, to help with this. @ISA governs (method) inheritance. Following are noteable points while using inheritance
Perl searches the class of the specified object for the specified object. Perl searches the classes defined in the object class's @ISA array. If no method is found in steps 1 or 2, then Perl uses an AUTOLOAD subroutine, if one is found in the @ISA tree.
If a matching method still cannot be found, then Perl searches for the method within the UNIVERSAL class (package) that comes as part of the standard Perl library. If the method still hasn't been found, then Perl gives up and raises a runtime exception.
So to create a new Employee class that will inherit methods and attributes from our Person class, we simply code: Keep this code into Employee.pm
#!/usr/bin/perl package Employee; use Person; use strict; our @ISA = qw(Person);
Now Employee Class has all the methods and attributes inherited from Person class and you can use it as follows: Use main.pl file to test it
#!/usr/bin/perl use Employee; $object = new Employee( "Mohammad", "Saleem", 23234345); # Get first name which is set using constructor. $firstName = $object->getFirstName(); print "Before Setting First Name is : $firstName\n"; # Now Set first name using helper function. $object->setFirstName( "Mohd." ); # Now get first name set by helper function. $firstName = $object->getFirstName(); print "After Setting First Name is : $firstName\n"; This will produce following result First Name is Mohammad Last Name is Saleem SSN is 23234345 Before Setting First Name is : Mohammad Before Setting First Name is : Mohd.
Method Overriding
The child class Employee inherits all the methods from parent class Person. But if you would like to override those methods in your child class then you can do it by givig your implementation. You can add your additional functions in child class. It can done as follows: modify Employee.pm file
#!/usr/bin/perl package Employee; use Person; use strict; our @ISA = qw(Person); # Override constructor sub new {
my ($class) = @_; # Call the constructor of the parent class, Person. my $self = $class->SUPER::new( $_[1], $_[2], $_[3] ); # Add few more attributes $self->{_id} = undef; $self->{_title} = undef; bless $self, $class; return $self; } # Override helper function sub getFirstName { my( $self ) = @_; # This is child class function. print "This is child class helper function\n"; return $self->{_firstName}; } # Add more methods sub setLastName{ my ( $self, $lastName ) = @_; $self->{_lastName} = $lastName if defined($lastName); return $self->{_lastName}; } sub getLastName { my( $self ) = @_; return $self->{_lastName}; } 1;
Now put following code into main.pl and execute it.
#!/usr/bin/perl use Employee; $object = new Employee( "Mohammad", "Saleem", 23234345); # Get first name which is set using constructor. $firstName = $object->getFirstName(); print "Before Setting First Name is : $firstName\n"; # Now Set first name using helper function. $object->setFirstName( "Mohd." ); # Now get first name set by helper function. $firstName = $object->getFirstName(); print "After Setting First Name is : $firstName\n"; This will produce following result First Name is Mohammad Last Name is Saleem SSN is 23234345 This is child class helper function Before Setting First Name is : Mohammad This is child class helper function After Setting First Name is : Mohd.
Default Autoloading
Perl offers a feature which you would not find any many other programming languages: a default subroutine. If you define a function called AUTOLOAD() then any calls to undefined subroutines will call AUTOLOAD() function. The name of the missing subroutine is accessible within this subroutine as $AUTOLOAD. This function is very useful for error handling purpose. Here is an example to implement AUTOLOAD, you can implement this function in your way.
sub AUTOLOAD { my $self = shift; my $type = ref ($self) || croak "$self is not an object"; my $field = $AUTOLOAD; $field =~ s/.*://; unless (exists $self->{$field}) { croak "$field does not exist in object/class $type"; } if (@_) { return $self->($name) = shift; } else { return $self->($name); } }
object reference's variable goes out of scope. object reference's variable is undef-ed script terminates perl interpreter terminates
For Example:
DATABASE MANAGEMENT
This session will teach you how to access Oracle Database and other databases using PERL.
Oraperl Module to access Oracle. Check Oraperl Mnual DBI module to access databases in generic way. We will discuss this module in this chapter.
Starting from Perl 5 it has become very easy to write database applications using DBI. DBI stands for Database independent interface for Perl which means DBI provides an abstraction layer between the Perl code and the underlying database, allowing you to switch database implementations really easily. The DBI is a database access module for the Perl programming language. It defines a set of methods, variables, and conventions that provide a consistent database interface, independent of the actual database being used.
Here DBI is responsible of taking all SQL commands through the API, or Application Programming Interface, and to dispatch them to the appropriate driver for actual execution. And finally DBI is responsible of taking results from the driver and giving back it to the calling scritp.
Database source name Database handle object Statement handle object Any of the handle types above ($dbh, $sth, or $drh) General Return Code (boolean: true=ok, false=error) General Return Value (typically an integer) List of values returned from the database.
Number of rows processed (if available, else -1) A filehandle NULL values are represented by undefined values in Perl Reference to a hash of attribute values passed to methods
Database Connection
Assuming we are going to work with MySQL database. Before connecting to a database make sure followings:
You have created a database TESTDB. You have created TEST_TABLE in TESTDB. This table is having fields FIRST_NAME, LAST_NAME, AGE, SEX and INCOME. User ID "testuser" and password "test123" are set to access TESTDB Perl Module DBI is installed properly on your machine. You have gone through MySQL tutorial to understand MySQL Basics.
#!/usr/bin/perl use DBI use strict; my my my my my my $driver = "mysql"; $database = "TESTDB"; $dsn = "DBI:$driver:database=$database"; $userid = "testuser"; $password = "test123"; $dbh = DBI->connect($dsn, $userid, $password ) or die $DBI::errstr;
If a connection is established with the datasource then a Database Handle is returned and saved into $dbh for further use otherwise $dbh is set to undef value and $DBI::errstr returns an error string.
INSERT Operation
INSERT operation is required when you want to create your records into TEST_TABLE. So once our database connection is established, we are ready to create records into TEST_TABLE. Following is the procedure to create single record into TEST_TABLE. You can create many records in similar fashion. Record creation takes following steps
Prearing SQL statement with INSERT statement. This will be done using prepare() API. Executing SQL query to select all the results from the database. This will be done usingexecute() API. Releasing Stattement handle. This will be done using finish() API If everything goes fine then commit this operation otherwise you can rollback complete transaction. Commit and Rollback are explained in next sections.
my $sth = $dbh->prepare("INSERT INTO TEST_TABLE (FIRST_NAME, LAST_NAME, SEX, AGE, INCOME ) values
('john', 'poul', 'M', 30, 13000)"); $sth->execute() or die $DBI::errstr; $sth->finish(); $dbh->commit or die $DBI::errstr;
my my my my my my
$first_name = "john"; $last_name = "poul"; $sex = "M"; $income = 13000; $age = 30; $sth = $dbh->prepare("INSERT INTO TEST_TABLE (FIRST_NAME, LAST_NAME, SEX, AGE, INCOME ) values (?,?,?,?)"); $sth->execute($first_name,$last_name,$sex, $age, $income) or die $DBI::errstr; $sth->finish(); $dbh->commit or die $DBI::errstr;
READ Operation
READ Operation on any databasse means to fetch some useful information from the database. So once our database connection is established, we are ready to make a query into this database. Following is the procedure to query all the records having AGE greater than 20. This will take four steps
Prearing SQL query based on required conditions. This will be done using prepare() API. Executing SQL query to select all the results from the database. This will be done usingexecute() API. Fetching all the results one by one and printing those results.This will be done usingfetchrow_array() API. Releasing Stattement handle. This will be done using finish() API
my $sth = $dbh->prepare("SELECT FIRST_NAME, LAST_NAME FROM TEST_TABLE WHERE AGE > 20"); $sth->execute() or die $DBI::errstr; print "Number of rows found :" + $sth->rows; while (my @row = $sth->fetchrow_array()) { my ($first_name, $last_name ) = @row; print "First Name = $first_name, Last Name = $last_name\n"; } $sth->finish();
$age = 20;
my $sth = $dbh->prepare("SELECT FIRST_NAME, LAST_NAME FROM TEST_TABLE WHERE AGE > ?"); $sth->execute( $age ) or die $DBI::errstr; print "Number of rows found :" + $sth->rows; while (my @row = $sth->fetchrow_array()) { my ($first_name, $last_name ) = @row; print "First Name = $first_name, Last Name = $last_name\n"; } $sth->finish();
UPDATE Operation
UPDATE Operation on any databasse means to update one or more records already available in the database. Following is the procedure to update all the records having SEX as 'M'. Here we will increase AGE of all the males by one year. This will take three steps
Prearing SQL query based on required conditions. This will be done using prepare() API. Executing SQL query to select all the results from the database. This will be done usingexecute() API. Releasing Stattement handle. This will be done using finish() API If everything goes fine then commit this operation otherwise you can rollback complete transaction. See next section for commit and rollback APIs.
my $sth = $dbh->prepare("UPDATE TEST_TABLE SET AGE = AGE + 1 WHERE SEX = 'M'"); $sth->execute() or die $DBI::errstr; print "Number of rows updated :" + $sth->rows; $sth->finish(); $dbh->commit or die $DBI::errstr;
$sex = 'M'; my $sth = $dbh->prepare("UPDATE TEST_TABLE SET AGE = AGE + 1 WHERE SEX = ?"); $sth->execute('$sex') or die $DBI::errstr; print "Number of rows updated :" + $sth->rows; $sth->finish(); $dbh->commit or die $DBI::errstr;
In some case you would like to set a value which is not given in advance so you can use binding value as follows. In this example income of all males will be set to 10000.
$sex = 'M'; $income = 10000; my $sth = $dbh->prepare("UPDATE TEST_TABLE SET INCOME = ? WHERE SEX = ?"); $sth->execute( $income, '$sex') or die $DBI::errstr; print "Number of rows updated :" + $sth->rows;
$sth->finish();
DELETE Operation
DELETE operation is required when you want to delete some records from your database. Following is the procedure to delete all the records from TEST_TABLE where AGE is equal to 30. This operation will take following steps.
Prearing SQL query based on required conditions. This will be done using prepare() API. Executing SQL query to delete required records from the database. This will be done usingexecute() API. Releasing Stattement handle. This will be done using finish() API If everything goes fine then commit this operation otherwise you can rollback complete transaction.
$age = 30; my $sth = $dbh->prepare("DELETE FROM TEST_TABLE WHERE AGE = ?"); $sth->execute( $age ) or die $DBI::errstr; print "Number of rows deleted :" + $sth->rows; $sth->finish(); $dbh->commit or die $DBI::errstr;
Using do Statement
If you're doing an UPDATE, INSERT, or DELETE there is no data that comes back from the database, so there is a short cut to perform this operation. You can use do statement to execute any of the command as follows.
COMMIT Operation
Commit is the operation which gives a green signal to database to finalize the changes and after this operation no change can be reverted back. Here is a simple example to call commit API.
ROLLBACK Operation
If you are not satisfied with all the changes and you want to revert back those changes then userollback API. Here is a simple example to call rollback API.
Begin Transaction
Many databases support transactions. This means that you can make a whole bunch of queries which would modify the databases, but none of the changes are actually made. Then at the end you issue the special SQL query COMMIT, and all the changes are made simultaneously. Alternatively, you can issue the query ROLLBACK, in which case all the queries are thrown away. begin_work API enables transactions (by turning AutoCommit off) until the next call to commit or rollback. After the next commit or rollback, AutoCommit will automatically be turned on again.
$rc
= $dbh->begin_work
or die $dbh->errstr;
AutoCommit Option
If your transactions are simple, you can save yourself the trouble of having to issue a lot of commits. When you make the connect call, you can specify an AutoCommit option which will perform an automatic commit operation after every successful query. Here's what it looks like:
Disconnecting Database
To disconnect Database connection, use disconnect API.
$rc = $dbh->disconnect
or warn $dbh->errstr;
The transaction behaviour of the disconnect method is, sadly, undefined. Some database systems (such as Oracle and Ingres) will automatically commit any outstanding changes, but others (such as Informix) will rollback any outstanding changes. Applications not using AutoCommit should explicitly call commit or rollback before calling disconnect.
$sth = $dbh->prepare(qq{ INSERT INTO TEST_TABLE (FIRST_NAME, AGE) VALUES (?, ?) }); $sth->execute("Joe", undef);
Here qq{} is used to return q quoted string to prepare API. However, care must be taken when trying to use NULL values in a WHERE clause. Consider:
$sql_clause = defined $age? "age = ?" : "age IS NULL"; $sth = $dbh->prepare(qq{ SELECT FIRST_NAME FROM TEST_TABLE WHERE $sql_clause }); $sth->execute(defined $age ? $age : ());
installed_drivers
%drivers = DBI->installed_drivers();
Returns a list of driver name and driver handle pairs for all drivers 'installed' (loaded) into the current process. The driver name does not include the 'DBD::' prefix.
data_sources
@ary = DBI->data_sources($driver);
Returns a list of data sources (databases) available via the named driver. If $driver is empty or undef, then the value of the DBI_DRIVER environment variable is used.
quote
$sql = sprintf "SELECT foo FROM bar WHERE baz = %s", $dbh->quote("Don't");
For most database types, quote would return 'Don''t' (including the outer quotation marks). It is valid for the quote() method to return an SQL expression that evaluates to the desired string. For example:
$quoted = $dbh->quote("one\ntwo\0three") may produce results which will be equivalent to CONCAT('one', CHAR(12), 'two', CHAR(0), 'three')
errstr
$str = $h->errstr; or $str = $DBI::errstr or $str = $h->errstr
Returns the native database engine error message from the last DBI method called. This has the same lifespan issues as the "err" method described above. This is equivalent to $DBI::errstr or $h>errstr.
rows
$rv = $h->rows; or $rv = $DBI::rows
This returns the number of rows effected by previous SQL statement and equivalent to $DBI::rows.
trace
$h->trace($trace_settings);
DBI sports an extremely useful ability to generate runtime tracing information of what it's doing, which can be a huge time-saver when trying to track down strange problems in your DBI programs. You can use different values to set trace level. These values varies from 0 to 4. The value 0 means disable trace and 4 means generate complete trace.
while ($first_name = <>) { my $sth = $dbh->prepare("SELECT * FROM TEST_TABLE WHERE FIRST_NAME = '$first_name'"); $sth->execute(); # and so on ... }
There are following reasons to avoid interploated statements:
First, prepare calls can take a long time. The database server has to compile the SQL and figure out how it is going to run the query. If you have many similar queries, that is a waste of time. Second, it will not work if $first_name contains a name like O'Brien or D'Fecto or some other name with an '. The ' has a special meaning in SQL, and the database will not understand when you ask it to prepare an SQL statement. Finally, if you're going to be constructing your query based on a user input then it's unsafe to simply interpolate the input directly into the query, because the user can construct a strange input in an attempt to trick your program into doing something it didn't expect. For example, suppose the user enters the following bizarre value for $input:
SELECT * FROM TEST_TABLE WHERE first_name = 'x' or first_name = first_name or first_name = 'y'
The part of this query that our sneaky user is interested in is the second or clause. This clause selects all the records for which first_name is equal to first_name; that is, all of them. Thus don't use interpolated statement instead use bind value to prepare dynamic SQL statement.
CGI PROGRAMMING
What is CGI ?
The Common Gateway Interface, or CGI, is a set of standards that define how information is exchanged between the web server and a custom script. The CGI specs are currently maintained by the NCSA and NCSA defines CGI is as follows: The Common Gateway Interface, or CGI, is a standard for external gateway programs to interface with information servers such as HTTP servers.
Web Browsing
To understand the concept of CGI, lets see what happens when we click a hyper link to browse a particular web page or URL.
Your browser contacts the HTTP web server and demand for the URL ie. filename. Web Server will parse the URL and will look for the filename in if it finds that file then sends back to the browser otherwise sends an error message indicating that you have requested a wrong file. Web browser takes response from web server and displays either the received file or error message.
However, it is possible to set up the HTTP server so that whenever a file in a certain directory is requested that file is not sent back; instead it is executed as a program, and whatever that program outputs is sent back for your browser to display. This function is called the Common Gateway Interface or CGI and the programs are called CGI scripts. These CGI programs can be a PERL Script, Shell Script, C or C++ program etc.
Here is a simple link which is linked to a CGI script called hello.cgi. This file is being kept in /cgi-bin/ directory and it has following content. Before running your CGI program make sure you have chage mode of file using chmod 755 hello.cgi UNIX command.
#!/usr/bin/perl print print print print print print print print print 1; If you click hello.cgi then this produces following output: "Content-type:text/html\r\n\r\n"; '<html>'; '<head>'; '<title>Hello Word - First CGI Program</title>'; '</head>'; '<body>'; '<h2>Hello Word! This is my first CGI program</h2>'; '</body>'; '</html>';
This hello.cgi script is a simple PERL script which is writing its output on STDOUT file ie. screen. There is one important and extra feature available which is first line to be printed Contenttype:text/html\r\n\r\n. This line is sent back to the browser and specifiy the content type to be displayed on the browser screen. Now you must have undertood basic concept of CGI and you can write many complicated CGI programs using PERL. This script can interact with any other exertnal system also to exchange information such as RDBMS.
HTTP Header
The line Content-type:text/html\r\n\r\n is part of HTTP header which is sent to the browser to understand the content. All the HTTP header will be in the following form
Description A MIME string defining the format of the file being returned. Example is Content-type:text/html The date the information becomes invalid. This should be used by the browser to decide when a page needs to be refreshed. A valid date string should be in the format 01 Jan 1998 12:00:00 GMT. The URL that should be returned instead of the URL requested. You can use this filed to redirect a request to any file.
The date of last modification of the resource. The length, in bytes, of the data being returned. The browser uses this value to report the estimated download time for a file. Set the cookie passed through the string
Here is small CGI program to list out all the CGI variables. Click this link to see the result Get Environment
#!/usr/bin/perl print "Content-type: text/html\n\n"; print "<font size=+1>Environment</font>\n"; foreach (sort keys %ENV) {
#!/usr/bin/perl # HTTP Header print "Content-Type:application/octet-stream; name=\"FileName\"\r\n"; print "Content-Disposition: attachment; filename=\"FileName\"\r\n\n"; # Actual File Content will go hear. open( FILE, "<FileName" ); while(read(FILE, $buffer, 100) ) { print("$buffer"); }
http://www.test.com/cgi-bin/hello.cgi?key1=value1&key2=value2
The GET method is the defualt method to pass information from browser to web server and it produces a long string that appears in your browser's Location:box. Never use the GET method if you have password or other sensitive information to pass to the server. The GET method has size limtation: only 1024 characters can be in a request string. This information is passed using QUERY_STRING header and will be accessible in your CGI Program through QUERY_STRING environment variable You can pass information by simply concatenating key and value pairs alongwith any URL or you can use HTML <FORM> tags to pass information using GET method.
#!/usr/bin/perl local ($buffer, @pairs, $pair, $name, $value, %FORM); # Read in text $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "GET") { $buffer = $ENV{'QUERY_STRING'}; } # Split information into name/value pairs @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex($1))/eg; $FORM{$name} = $value; } $first_name = $FORM{first_name}; $last_name = $FORM{last_name}; print print print print print print print print print 1; "Content-type:text/html\r\n\r\n"; "<html>"; "<head>"; "<title>Hello - Second CGI Program</title>"; "</head>"; "<body>"; "<h2>Hello $first_name $last_name - Second CGI Program</h2>"; "</body>"; "</html>";
<FORM action="/cgi-bin/hello_get.cgi" method="GET"> First Name: <input type="text" name="first_name"> <br> Last Name: <input type="text" name="last_name"> <input type="submit" value="Submit"> </FORM>
Here is the actual output of the above form, You enter First and Last Name and then click submit button to see the result.
First Name:
Last Name:
Submit
#!/usr/bin/perl local ($buffer, @pairs, $pair, $name, $value, %FORM); # Read in text $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }else { $buffer = $ENV{'QUERY_STRING'}; } # Split information into name/value pairs @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex($1))/eg; $FORM{$name} = $value; } $first_name = $FORM{first_name}; $last_name = $FORM{last_name}; print print print print print print print print print 1;
Let us take again same examle as above, which passes two values using HTML FORM and submit button. We are going to use CGI script hello_post.cgi to handle this imput.
"Content-type:text/html\r\n\r\n"; "<html>"; "<head>"; "<title>Hello - Second CGI Program</title>"; "</head>"; "<body>"; "<h2>Hello $first_name $last_name - Second CGI Program</h2>"; "</body>"; "</html>";
<FORM action="/cgi-bin/hello_post.cgi" method="POST"> First Name: <input type="text" name="first_name"> <br> Last Name: <input type="text" name="last_name">
First Name:
Last Name:
Submit
<form action="/cgi-bin/checkbox.cgi" method="POST" target="_blank"> <input type="checkbox" name="maths" value="on"> Maths <input type="checkbox" name="physics" value="on"> Physics <input type="submit" value="Select Subject"> </form>
The result of this code is the following form
Select Subject
Maths
Physics
Below is checkbox.cgi script to handle input given by web browser for radio button.
#!/usr/bin/perl local ($buffer, @pairs, $pair, $name, $value, %FORM); # Read in text $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }else { $buffer = $ENV{'QUERY_STRING'}; } # Split information into name/value pairs @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex($1))/eg; $FORM{$name} = $value; } if( $FORM{maths} ){
$maths_flag ="ON"; }else{ $maths_flag ="OFF"; } if( $FORM{physics} ){ $physics_flag ="ON"; }else{ $physics_flag ="OFF"; } print print print print print print print print print print 1; "Content-type:text/html\r\n\r\n"; "<html>"; "<head>"; "<title>Checkbox - Third CGI Program</title>"; "</head>"; "<body>"; "<h2> CheckBox Maths is : $maths_flag</h2>"; "<h2> CheckBox Physics is : $physics_flag</h2>"; "</body>"; "</html>";
<form action="/cgi-bin/radiobutton.cgi" method="POST" target="_blank"> <input type="radio" name="subject" value="maths"> Maths <input type="radio" name="subject" value="physics"> Physics <input type="submit" value="Select Subject"> </form>
The result of this code is the following form
Select Subject
Maths
Physics
Below is radiobutton.cgi script to handle input given by web browser for radio button.
#!/usr/bin/perl local ($buffer, @pairs, $pair, $name, $value, %FORM); # Read in text $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }else { $buffer = $ENV{'QUERY_STRING'}; } # Split information into name/value pairs @pairs = split(/&/, $buffer); foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex($1))/eg; $FORM{$name} = $value; } $subject = $FORM{subject}; print print print print print print print print print 1; "Content-type:text/html\r\n\r\n"; "<html>"; "<head>"; "<title>Radio - Fourth CGI Program</title>"; "</head>"; "<body>"; "<h2> Selected Subject is $subject</h2>"; "</body>"; "</html>";
<form action="/cgi-bin/textarea.cgi" method="POST" target="_blank"> <textarea name="textcontent" cols=40 rows=4> Type your text here... </textarea> <input type="submit" value="Submit"> </form>
The result of this code is the following form
Submit
#!/usr/bin/perl local ($buffer, @pairs, $pair, $name, $value, %FORM); # Read in text $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }else { $buffer = $ENV{'QUERY_STRING'}; } # Split information into name/value pairs @pairs = split(/&/, $buffer); foreach $pair (@pairs)
{ ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex($1))/eg; $FORM{$name} = $value; } $text_content = $FORM{textcontent}; print print print print print print print print print 1; "Content-type:text/html\r\n\r\n"; "<html>"; "<head>"; "<title>Text Area - Fifth CGI Program</title>"; "</head>"; "<body>"; "<h2> Entered Text Content is $text_content</h2>"; "</body>"; "</html>";
<form action="/cgi-bin/dropdown.cgi" method="POST" target="_blank"> <select name="dropdown"> <option value="Maths" selected>Maths<option> <option value="Physics">Physics<option> </select> <input type="submit" value="Submit"> </form>
The result of this code is the following form
Submit
#!/usr/bin/perl local ($buffer, @pairs, $pair, $name, $value, %FORM); # Read in text $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }else { $buffer = $ENV{'QUERY_STRING'}; } # Split information into name/value pairs @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex($1))/eg; $FORM{$name} = $value; } $subject = $FORM{dropdown}; print print print print print print print print print 1; "Content-type:text/html\r\n\r\n"; "<html>"; "<head>"; "<title>Dropdown Box - Sixth CGI Program</title>"; "</head>"; "<body>"; "<h2> Selected Subject is $subject</h2>"; "</body>"; "</html>";
How It Works
Your server sends some data to the visitor's browser in the form of a cookie. The browser may accept the cookie. If it does, it is stored as a plain text record on the visitor's hard drive. Now, when the visitor arrives at another page on your site, the cookie is available for retrieval. Once retrieved, your server knows/remembers what was stored. Cookies are a plain text data record of 5 variable-length fields:
Expires : The date the cookie will expire. If this is blank, the cookie will expire when the visitor quits the browser. Domain : The domain name of your site. Path : The path to the directory or web page that set the cookie. This may be blank if you want to retrieve the cookie from any directory or page. Secure : If this field contains the word "secure" then the cookie may only be retrieved with a secure server. If this field is blank, no such restriction exists. Name=Value : Cookies are set and retrviewed in the form of key and value pairs.
Setting up Cookies
This is very easy to send cookies to browser. These cookies will be sent along with HTTP Header. Assuming you want to set UserID and Password as cookies. So it will be done as follows
print "Set-Cookie:Expires=Tuesday, 31-Dec-2007 23:12:40 GMT";\n"; print "Set-Cookie:Domain=www.tutorialspoint.com;\n"; print "Set-Cookie:Path=/perl;\n"; print "Content-type:text/html\r\n\r\n"; ...........Rest of the HTML Content....
From this example you must have understood how to set cookies. We use Set-Cookie HTTP header to set cookies. Here it is optional to set cookies attributes like Expires, Domain, and Path. It is notable that cookies are set before sending magic line "Content-type:text/html\r\n\r\n.
Retrieving Cookies
This is very easy to retrieve all the set cookies. Cookies are stored in CGI environment variable HTTP_COOKIE and they will have following form.
key1=value1;key2=value2;key3=value3....
Here is an example of how to retrieving cookies.
#!/usr/bin/perl $rcvd_cookies = $ENV{'HTTP_COOKIE'}; @cookies = split /;/, $rcvd_cookies; foreach $cookie ( @cookies ){ ($key, $val) = split(/=/, $cookie); # splits on the first =. $key =~ s/^\s+//; $val =~ s/^\s+//; $key =~ s/\s+$//; $val =~ s/\s+$//; if( $key eq "UserID" ){ $user_id = $val; }elsif($key eq "Password"){ $password = $val; } } print "User ID = $user_id\n"; print "Password = $password\n"; This will produce following result User ID = XYZ Password = XYZ123