Perl - Advanced
Download
Report
Transcript Perl - Advanced
Perl - Advanced
More Advanced Perl
Functions
Control Structures
Filehandles
Process Management
Perl Functions
Function – Sub routine
Definition
Keyword “sub” – Definition of a
sub routine
Name of the routine “subname”
Block Of statements {…}
sub subname {
statement_1;
statement_2;
statement_3;
}
Properties
Can be anywhere in the program
They are global – There are no local
subroutine definitions
Example
sub say_what {
print "hello, $what\n";
}
$what refers to a global $what shared to
the rest of the program
Invoking a User Function
We invoke a user function from within an expression by following
the subroutine name with parentheses.
or
say_what();
&say_what();
A subroutine can invoke another subroutine, and that subroutine
can in turn invoke another subroutine, and so on.
Return Values
A subroutine can return a single
value
A sub routine can return a list of
values
sub sum_of_a_and_b {
return $a + $b;
}
sub list_of_a_and_b {
return($a,$b);
}
Arguments
In Perl, the subroutine invocation is followed by a list within parentheses, causing the
list to be automatically assigned to a special variable named @_ for the duration of
the subroutine. The subroutine can access this variable to determine the number of
arguments and the value of those arguments:
($_[0,1,2…])
The @_ variable is private to the subroutine
Example on Arguments
sub add {
$sum = 0; # initialize the sum
foreach $_ (@_) {
$sum += $_; # add each element
}
return $sum; # last expression evaluated: sum of all elements
}
We invoke the above function by typing add($a, $b, …) where inside the
parentheses we put as many variables as we like.
The @_ variable is private to the subroutine. This also means that a subroutine
can pass arguments to another subroutine without fear of losing its own @_
variable; The nested subroutine invocation gets its own @_ in the same way.
Control Structures
The control expression is evaluated for a string value in scalar context (if it's already a
string, no change, but if it's a number, it is converted to a string)
The if/else statement
if (some expression one) {
true_statement_one_1;
true_statement_one_2;
true_statement_one_3;
} elseif (some expression two){
true_statement_two_4;
true_statement_two_5;
true_statement_two_6;
}else{
false_statement_1;
false_statement_2;
false_statement_3;
}
The unless statement
Replacing if with unless is in effect saying "If
the control expression is false, do...." (An
unless can also have an else, just like an if.)
The while Statement
while (some expression) {
statement_1;
statement_2;
statement_3;
}
Perl evaluates the control expression (some
expression in the example). If its value is
true, the body of the while statement is
evaluated once. This is repeated until the
control expression becomes false.
Examples of true and false
interpretations
Control Expression
Interpretation
0
converts to "0", so false
1-1
computes to 0, then converts to "0", so
false
1
converts to "1", so true
""
empty string, so false
"1"
not "" or "0", so true
"00"
not "" or "0", so true (this is weird, watch
out)
"0.000"
also true for the same reason and
warning
undef
evaluates to "", so false
Control Structures
The Until Statement
Sometimes it is easier to say "until something is true" rather than "while not this is
true." Once again, Perl has the answer. Replacing the while with until yields the
desired effect:
Note
until (some_expression) {
statement_1;
statement_2;
statement_3;
}
Both the while and the until form, the
body statements will be skipped entirely
if the control expression is the
termination value to begin with.
Control Structures
The do {} while/until Statement
The while/until statement you saw in the previous section tests its condition at the
top of every loop, before the loop is entered. If the condition was already false to
begin with, the loop won't be executed at all.
Perl provides the do {} while statement, which is just like the regular while
statement except that it doesn't test the expression until after executing the loop
once.
Syntax
do {
statement_1;
statement_2;
statement_3;
} while (some expression);
do { … } until (some expression);
As with a normal while loop, you can
invert the sense of the test by changing
do {} while to do {} until. The expression
is still tested at the bottom, but its sense
is reversed.
Control Structures
The for loop statement
Syntax
for ( initial_exp; test_exp; re-init_exp ) {
statement_1;
statement_2;
statement_3;
}
Example
for ($i=0; $i<=10; $i++)
{
print “Incrementing by one: $i”;
}
This expression typically assigns an initial value to an iterator variable, but there are
no restrictions on what it can contain; in fact, it may even be empty (doing nothing).
Then the test_exp expression is evaluated for truth or falsehood. If the value is true,
the body is executed, followed by the re-init_exp (typically, but not solely, used to
increment the iterator). Perl then reevaluates the test_exp, repeating as necessary.
Control Structures
The foreach statement
This statement takes a list of values and assigns them one at a time to a scalar
variable, executing a block of code with each successive assignment.
If the list you are iterating over is made of real variables rather than some function
returning a list value, then the variable being used for iteration is in fact an alias for
each variable in the list instead of being merely a copy of the values. It means that if
you change the scalar variable, you are also changing that particular element in the
list that the variable is standing in for.
foreach $i (@some_list) {
statement_1;
statement_2;
statement_3;
}
@list = (3,5,7,9);
$counter=0;
foreach $tmp (@ list) {
$tmp *= 3;
$list[$counter] = $tmp;
$counter++;
}
# @ list is now (9,15,21,27)
Filehandles
A filehandle in a Perl program is the name for an I/O connection between your Perl
process and the outside world. We've already seen and used filehandles implicitly:
STDIN is a filehandle, naming the connection between the Perl process and the UNIX
standard input.
Filehandles are used without a special prefix character.
TIP : use ALL UPPERCASE letters in your filehandle. not only will it stand out better,
but it will also guarantee that your program won't fail when a future reserved word is
introduced.
Use the open function to open additional filehandles. The syntax looks like this:
open(FILEHANDLE,"somename"); where FILEHANDLE is the new filehandle
and somename is the external filename (such as a file or a device)
When we are finished with a filehandle, we may close it with the close operator, like
so:
close(FILEHANDLE);
Filehandles
writing or appending
reading
To open a file for writing, use the same
open function, but prefix the filename
with a greater-than sign (as in the shell):
Once a filehandle is open for reading,
you can read lines from it just as you can
read from standard input with STDIN. So,
for example, to read lines from the
password file:
open(OUT, ">outfile");
We can now invoke the print
function to write to the file ‘outfile’
like this: print OUT “text to write to
the outfile”;
We can open a file for appending by
using two greater-than signs for a prefix,
as in: open(LOGFILE, ">>mylogfile");
open (IN, “/etc/passwd”);
while(<IN>)
{
chomp($_);
print "I saw $_ in the password
file!\n";
}
Filehandles example
Reading from a file into another
open (IN, “file1”);
open (OUT, “>>file2”)
#opening file1 for reading
#opening file2 for writing
while (<IN>)
{
print OUT “$_”;
}
#reading line by line from file1 until empty line occurs
close (IN);
close (OUT);
# append in file2 last line read from file1
#closing file1
#closing file2
Process Management
A Perl program can launch new processes, and like most other operations, has more
than one way to do so.
Using the system function
In its simplest form, this function
hands a single string to a brand new
/bin/sh shell to be executed as a
command.
For the system function, the three
standard files (standard input, standard
output, and standard error) are inherited
from the Perl process.
The argument to system can be
anything you would feed /bin/sh, so
multiple commands can be included,
separated by semicolons or newlines.
Examples
system (“date”); # executes the date
command
To put the output of the date
command into a file named right_now,
something like this will work just fine:
system("date >right_now") || die "cannot
create right_now";
system(“date; ls;”);
Using Processes as Filehandles
Another way to launch a process is to create a process that looks like a filehandle
We can create a process-filehandle that either captures the output from or provides
input to the process
Input
Output
Because the process is generating output
that we want to read, we make a
filehandle that is open for reading, like
so:
open(WHOPROC, "who|"); # open who
for reading
Note the vertical bar on the right side
of who. That bar tells Perl that this open
is not about a filename, but rather a
command to be started. Because the bar
is on the right of the command, the
filehandle is opened for reading, meaning
that the standard output of who is going
to be captured.
Similarly, to open a command that expects
input, we can open a process-filehandle
for writing by putting
the vertical bar on the left of the
command, like so:
open(LPR,"|lpr -Pslatewriter");
Using Processes as Filehandles
ATTENTION
Opening a process with a process-filehandle allows the command to execute in
parallel with the Perl program. Saying close on the filehandle forces the Perl
program to wait until the process exits. If you don't close the filehandle, the
process can continue to run even beyond the execution of the Perl program.
You don't have to open just one command at a time. You can open an entire
pipeline. For example, the following line starts up an ls (1) process, which pipes
its output into a tail (1) process, which finally sends its output along to the
WHOPR filehandle:
open(WHOPR, "ls | tail -r |");
Summary of Process Operations
System Function
It is the simplest way to create a
process.
Standard input, output, and error are
unaffected.
The process finishes before any more
code is executed.
As Filehandles
A simple way to get an asynchronous
process
It allows the Perl program to continue
before the process is complete
A command opened as a filehandle for
reading inherits the standard input and
standard error from the Perl program
A command opened as a filehandle for
writing inherits the standard output and
standard error from the Perl program.
Perl versus C
There are no type of variables
All scalars are declared with $name
Arrays are declared with @name
Hashes are new collection of scalar data, with individual elements selected by some
index value
Hashes are declared with %name
Same control structures if/elsif/else, while, do{…}while
New control structures until, unless, do{…}unless, foreach, each
Function arguments are not declared in the definition of the function. Instead are
automatically imported and we can give on each function call an arbitrary number of
arguments. Then they can be accessed through the @_ predefined variable
Calling system commands, regular expressions, file manipulation are very powerful
on perl.
Exercises
Write a subroutine to take a numeric value from 1 to 9 as an argument and return
the English name (such as one, two, or nine). If the value is out of range, return the
original number as the name instead.
Write a program to read in a filename from STDIN, then open that file and display
its contents with each line preceded by the filename and a colon. For example, if fred
was read in, and the file fred consisted of the three lines aaa, bbb, and ccc, you would
see fred: aaa, fred: bbb, and fred: ccc.
Write a program to parse the output of the date command to get the current day of
the week. If the day of the week is a weekday, print get to work, otherwise print go
play in a file named weekday.
Write a program that reads in a string, then prints that string and its mapped value
according to the mapping presented in the following table:
• Input Output
• red apple
• green leaves
• blue ocean