User Defined Functions
&hello;
do hello();
$mood = "great";
&show_mood;
# Now mood is depressing.
sub show_mood
{ print "I feel $mood.\n";
$mood = "depressing";
}
# sub add from Llama.
sub add
{ local ($sum) = 0;
foreach (@_)
{ $sum += $_;
}
$sum;
}
sub hello
{ my ($fname, $lname) = @_;
print "Welcome to UHCL, $fname
$lname!\n";
}
# passing.pl
$a = 10;
$b = 20;
dummy1($a, $b);
print "\$a = $a\n";
print "\$b = $b\n";
$a = 10;
$b = 20;
dummy2($a, $b);
print "\$a = $a\n";
print "\$b = $b\n";
sub dummy1 {
$_[0] = 50;
$_[1] = 60;
}
sub dummy2 {
my ($arg1, $arg2) = @_;
$arg1 = 50;
$arg2 = 60;
}
Exercise 1:
Write a Perl subroutine max, which takes a list of numbers and returns the largest value.
Exercise 2:
Write a function which accepts a yes-or-no question and prompt for user input: "yes" or "no". Return 1 if users typed in 'y' or 'Y'. Return 0 if 'n' or 'N'. Otherwise, repeat the prompt until a valid response is typed in.
Exercise 3:
Write a Perl subroutine date to accept a string of date of format "mm/dd/yy" and return a string of date of format "month day, year". For example, if the input is "09/17/96", the output is "September 17, 1996".
System-Defined Functions
The function splice(ARRAY, OFFSET, LENGTH, LIST) replaces ARRAY[OFFSET ..OFFSET+LENGTH-1} by LIST. It returns the replaced substring.
#!/opt/gnu/bin/perl
# Alternate solution for randomly printing
strings.
srand;
@list = <STDIN>;
while (@list)
{ $string = splice(@list, rand @list,
1);
print $string;
}
Packages
# A priority queue.
sub add_entry
{ package Priority_Queue;
local ($priority, $message)
= @_;
for ($i=0; $i <= $#queue;
$i++)
{ last if $priority >
$queue[$i];
}
splice(@queue, $i, 0, "$priority:$message");
}
sub next_entry
{ package Priority_Queue;
return () unless @queue;
split(/:/, shift(@queue), 2);
}
# Print all messages from 'main'.
foreach (@Priority_Queue'queue)
{ print s/.*://;
}
Modules
References
Symbolic References
#!/opt/gnu/bin/perl
@num = (2, 5, 8);
print "The numbers: @num.\n";
&process_num(@num);
print "The numbers are now: @num.\n";
sub process_num {
print "The last number is ",
pop(@_), ". It is removed.\n";
foreach (@_) {
$_++;
}
}
#!/opt/gnu/bin/perl
@num = (2, 5, 8);
print "The numbers: @num.\n";
&process_num(*num);
print "The numbers are now: @num.\n";
sub process_num {
local(*para) = @_;
print "The number of parameter
passed: " , scalar(@_), ".\n";
print "The last number is ",
pop(@para), ". It is removed.\n";
foreach (@para) {
$_++;
}
}
Hard References
$scalarref = \$m;
$arrayref = \@ARGV;
$hashref = \%ENV;
$coderef = \&handler;
$globref = \*STDOUT;
$reftoref = \$scalarref;
$constref=\1997.5;
$name="Bun Yue";
$q = 10;
$p = \$q;
print "\$p is ", $p, ".\n";
print "\$\$p is ", $$p, ".\n";
@nums = (1, 2, 3, 4);
$r = \@nums;
print "\$r is ", $r, ".\n";
print "\@\$r is ", @$r, ".\n";
The output looks like:
$p is SCALAR(0xb75e0c).
$$p is 10.
$r is ARRAY(0xb75e9c).
@$r is 1234.
Example 2.2: redoing 1.1 using hard references.
#!/opt/gnu/bin/perl
@num = (2, 5, 8);
print "The numbers: @num.\n";
&process_num(\@num);
print "The numbers are now: @num.\n";
sub process_num {
local($ref) = @_;
print "The number of parameter
passed: " , scalar(@_), ".\n";
print "The last number is ",
pop(@$ref), ". It is removed.\n";
foreach (@$ref) {
$_++;
}
}
Suggested Solutions To Module #3
1. For example,
sub max
{ local ($max) = pop(@_);
foreach (@_)
{ $max = $_ if $_ > $max;
}
$max;
}
2. For example,
sub yes_or_no
{ local($answer);
for (;;)
{ print "@_[0] [y/n].\n==>
";
$answer =
<STDIN>;
return 1 if
$answer =~ /^y/i;
return 0 if
$answer =~ /^n/i;
}
}
3. For example,
sub date
{ local (@month) = ('January', 'February',
'March',
'April', 'May', 'June',
'July', 'August', 'September',
'October', 'November', 'December');
local ($m, $d, $y) = split(/\//, (shift
@_));
return "$month[$m-1]" . " $d, 19$y";
}