Transcript Subroutines

Subroutines
• Just like C, PERL offers the ability to use
subroutines for all the same reasons
– Code that you will use over and over again
– Breaking large programs into a series of smaller,
more manageable pieces
– Making programs more readable
– Making programs easier to test
– Allowing for multiple programmers to work on a
single program
Subroutines
• Recall from C
– Subroutines have a name
– Subroutines have an argument/parameter list for
input values
– Subroutines have a return type for output value(s)
– Subroutine variables have local (to the subroutine)
scope
• PERL is no different in these respects except
for the last item – scope
Scope in PERL
• When a variable is used without declaring it, by
definition it has global scope
– That is, it can be used anywhere within the program
$str = ‘abcde’;
$regexp = ‘^ab*a$’;
– Both $str and $regexp are globally scoped variables
– If their contents is changed from within a subroutine, it will
also change outside of the subroutine
• This is not how C works
Scope in PERL
• But, this “feature” of PERL can be turned off though
the use of a special keyword/construct
$str = ‘abc’;
print $str, “\n”;
can be changed to
my($str) = ‘abc’;
print $str, “\n”;
to make the variable $str locally scoped to the block
in which it is being used
Scope in PERL
• Enforcing scope and variable declaration
– Also recall that in C we absolutely must declare all
variables prior to usage
– PERL has no such restriction
• Causes problems if you misspell variable names
• Causes problems if you use the same variable name more than
once
– We can make PERL act like C by including the following
directive (it’s not a PERL code statement) at the top of our
code file
use strict;
Scope in PERL
• This program will not compile:
use strict;
$str = ‘abc’;
print $str, “\n”;
• But this one will
use strict;
my($str) = ‘abc’;
print $str, “\n”;
• Note that there is still no data typing!
• We’re just declaring the usage of a variable name
Back to subroutines
• Subroutine format
sub mysubroutine {
my($arg) = @_;
my($localvar);
# do something here
return $localvar;
}
Argument passing
• All of the previous should be fairly clear except for
the line
my($arg) = @_;
• This is how arguments are passed in
– Note that there is no argument list in the subroutine
definition
– Arguments get lumped together as a special array called _
(underscore)
– The line above pulls the arguments out of the array and
places them into locally scoped scalar variables (just one in
this example)
Argument passing
• More than one argument
my($arg1, $arg2) = @_;
• Arguments are passed by value
– Even if you alter their value within the subroutine, their
value on the outside remains unchanged
• Passing arrays gets complicated because they all get
lumped into a single array
– This can be avoided by passing by reference but…
– The syntax is horrible and I’m not going to burden you with
it during the last week of class
Calling a subroutine
• Just do the obvious…
$arg = ‘abc’;
$retvar = mysubroutine($arg);
print $retvar, “\n”;
• Or, better yet
my($arg) = ‘abc’;
my($retvar) = mysubroutine($arg);
print $retvar, “\n”;
Practice
• Write a subroutine that takes one argument and
returns it with the string “ modified by subroutine”
appended
– Recall the append is done with the . operator
$var = $var.‘append me’;
• Write a subroutine that takes two arguments, one
string and one regular expression, and returns 1 if
they match, 0 if the do not
– Read the string and the regular expression from the
keyboard (don’t forget to chomp them before sending to
the subroutine)
And more practice
• Convert your code to print out a file 30 lines at
a time to use a subroutine
– That is, make a subroutine that is called like this:
printfile($filename);
– In your main program, use a while loop to read a
filename from the keyboard, then print the file
– Halt the main program (while loop) when the user
types a carriage-return with no filename