You are on page 1of 42

Subroutines & Functions

Subroutines and Functions


Outline
Introduction
Subroutines in Perl
Built-in Math Functions
User-defined Subroutines
Argument Lists
Returning Values
Other Ways to Invoke a Subroutine
Random-Number Generators
Recursion
Example Using Recursion
Recursion vs. Iteration
Scope Rules: Global, Lexical and Dynamic
Packages and Modules
Defining a Package and
Importing it with require
Including Modules with the use Statement
Boss Worker Subroutine Relationship

boss

worker1 worker2 worker3

worker4 worker5

Hierarchical boss–subroutine/worker–subroutine relationship.


Built-in Functions
Function Description Example

Cos( $x ) trigonometric cos( 0 ) is 1


cosine of x
(x in radians)
Exp( $x ) e to the power of x exp( 1 ) is 2.71828
exp( 2 ) is 7.38906
Abs( $x ) absolute value of x abs( 5.1 ) is 5.1
abs( 0 ) is 0
abs( -8.76 ) is 8.76
Log( $x ) natural logarithm log( 2.718282 ) is 1
of x (base e) log( 7.389056 ) is 2
Sin( $x ) trigonometric sine sin( 0 ) is 0
of x
(x in radians)
sqrt( $x ) square root of x sqrt( 900 ) is 30
sqrt( 9 ) is 3
1 #!/usr/bin/perl
2 #
3 # Demonstrating some math functions.
4
5 $_ = -2;
6 print "Absolute value of 5 is: ", abs( 5 ),
"\n",
7 "Absolute value of -5 is: ", abs
(
8 -5 ), "\n",
"Absolute value of $_: ", abs, "\n\n";
9
10print "exp( $_ ): ", exp, "\n";
11print "log( 5 ): ", log( 5 ), "\n";
12print "sqrt( 16 ): ", sqrt( 16 ), "\n";

Absolute value of 5 is: 5


Absolute value of -5 is: 5
Absolute value of -2: 2

exp( -2 ): 0.135335283236613
log( 5 ): 1.6094379124341
sqrt( 16 ): 4
User Defined Subroutines
 User defined subroutines are defined using the key
word “sub” followed by the name of the subroutine.

 The statement which make up the subroutine are


enclosed between curly braces { }.

 The subroutine is invoked or called by using its name.

We do
Were
notdo
have
we the
define
concept
the of
subroutine
subroutine?
prototype.
1 #!/usr/bin/perl
2 #
3 # User-defined subroutines that take no arguments.
4
5 subroutine1(); # call the subroutine with no arguments
6 subroutine2(); # call the subroutine with no arguments
7
8 # the code after this comment executes only if the program
9 # explicitly calls these subroutines (as in lines 5 and
6).
10 sub subroutine1
11 {
12 print "called subroutine1\n";
13 }
14
15 sub subroutine2
16 {
17 print "called subroutine2\n";
18 }

called subroutine1
called subroutine2
Argument List
 The list of arguments passed to a subroutine are
stored in the special array variable @_.

 Using the for structure we can accesses each


argument individually, with the expression $_[ $i ],
and displays the argument value.
1 #!/usr/bin/perl
2 #
3 # Demonstrating a subroutine that receives arguments.
4
5 displayArguments( "Safa", "Jones", 2, 15, 73, 2.79 );
6
7 # output the subroutine arguments using special variable
@_
8 sub displayArguments
9 {
10 # the following statement displays all the arguments
11 print "All arguments: @_\n";
12
13 # the following loop displays each individual argument
14 for ( $i = 0; $i < @_; ++$i ) {
15 print "Argument $i: $_[ $i ]\n";
16 }
17}
Returning Values
 The subroutine can pass the result back to the caller
via the return keyword

 Functionshift, when used without any arguments,


operates on the @_ special array variable and
removes the first element of the array.
1 #!/usr/bin/perl
2 #
3 # Demonstrating a subroutine that returns a value.
4
5 # for the numbers from 1-10, call subroutine square
to
6 # square each value, and display each result
7 for ( 1 .. 10 ) {
8 print square( $_ ), " ";
9 }
10
11print "\n";
12
13# subroutine square returns the square of a number
14sub square
15{
16 $value = shift(); # use shift to get first
argument
17 return $value ** 2; # returns the result of
$value ** 2
18}
1 4 9 16 25 36 49 64 81 100
wantarray( ) Function
 When called in the body of a subroutine, function
wantarray( ) returns true if the subroutine was called
from a list context and returns false if the subroutine
was called from a scalar context.
1 #!/usr/bin/perl
2 #
3 # Demonstrating a subroutine that returns a scalar or a list.
4
5 # call scalarOrList() in list context to initialize @array,
6 # then print the list
7 @array = scalarOrList(); # list context to initialize @array
8 $" = "\n"; # set default separator character
9 print "Returned:\n@array\n";
10
11 # call scalarOrList() in scalar context and concatenate the
12 # result to another string
13 print "\nReturned: " . scalarOrList(); # scalar context
14
15 # use wantarray to return a list or scalar
16 # based on the calling context
17 sub scalarOrList
18 {
19 if ( wantarray() ) { # if list context
20 return 'this', 'is', 'a', 'list', 'of', 'strings';
21 }
22 else { # if scalar context
23 return 'hello';
24 }
25 }
Returned:
this
is
a
list
of
strings

Returned: hello

Do we have multiple ways of


invoking a subroutine.

If so how
Other Ways To Invoke a Subroutine
A subroutine could be defined either in the beginning
or at the end of the Perl program.

Subroutine Defined Before Use


Invoked with Without With
Using & and ( ) Arguments
OK Arguments
OK
Using only ( ) OK OK
Using only & OK Generates
Error
Using bareword OK OK
Other Ways To Invoke a Subroutine
A subroutine could be defined either in the beginning
or at the end of the Perl program.

Subroutine Defined After Use


Invoked with Without With
Using & and ( ) ArgumentsOK Arguments
OK
Using only ( ) OK OK
Using only & OK Generates
Error
Using bareword Causes no action Generates
Error
1 #!usr/bin/perl
2 #
3 # Syntax for calling a subroutine.
4
5 # subroutine with no arguments defined before it is used
6 sub definedBeforeWithoutArguments
7 {
8 print "definedBeforeWithoutArguments\n";
9 }
10
11 # subroutine with arguments defined before it is used
12 sub definedBeforeWithArguments
13 {
14 print "definedBeforeWithArguments: @_\n";
15 }
16
17 # calling subroutines that are defined before use
18 print "------------------------------\n";
19 print "Subroutines defined before use\n";
20 print "------------------------------\n";
21 print "Using & and ():\n";
22 &definedBeforeWithoutArguments();
23 &definedBeforeWithArguments( 1, 2, 3 );
24
25 print "\nUsing only ():\n";
26 definedBeforeWithoutArguments();
27 definedBeforeWithArguments( 1, 2, 3 );
28
29 print "\nUsing only &:\n";
30 &definedBeforeWithoutArguments;
31 print "\"&definedBeforeWithArguments 1, 2, 3\"",
32 " generates a syntax error\n";
33
34 print "\nUsing bareword:\n";
35 definedBeforeWithoutArguments;
36 definedBeforeWithArguments 1, 2, 3;
37
38 # calling subroutines that are not defined before use
39 print "\n-----------------------------\n";
40 print "Subroutines defined after use\n";
41 print "-----------------------------\n";
42 print "Using & and ():\n";
43 &definedAfterWithoutArguments();
44 &definedAfterWithArguments( 1, 2, 3 );
45
46 print "\nUsing only ():\n";
47 definedAfterWithoutArguments();
48 definedAfterWithArguments( 1, 2, 3 );
49
50 print "\nUsing only &:\n";
51 &definedAfterWithoutArguments;
52 print "\"&definedAfterWithArguments 1, 2, 3\"",
53 " generates a syntax error\n";
54
55 print "\nUsing bareword:\n";
56 definedAfterWithoutArguments;
57 print "\"definedAfterWithoutArguments\" causes no action\n";
58 print "\"definedAfterWithArguments 1, 2, 3\"",
59 " generates a syntax error\n";
60
61 # subroutine with no arguments defined after it is used
62 sub definedAfterWithoutArguments
63 {
64 print "definedAfterWithoutArguments\n";
65 }
66
67 # subroutine with arguments defined after it is used
68 sub definedAfterWithArguments
69 {
70 print "definedAfterWithArguments: @_\n";
71 }

------------------------------
Subroutines defined before use
------------------------------
Using & and ():
definedBeforeWithoutArguments
definedBeforeWithArguments: 1 2 3

Using only ():


definedBeforeWithoutArguments
definedBeforeWithArguments: 1 2 3

Using only &:


definedBeforeWithoutArguments
"&definedBeforeWithArguments 1, 2, 3" generates a syntax error

Using bareword:
definedBeforeWithoutArguments
definedBeforeWithArguments: 1 2 3
-----------------------------
Subroutines defined after use
-----------------------------
Using & and ():
definedAfterWithoutArguments
definedAfterWithArguments: 1 2 3

Using only ():


definedAfterWithoutArguments
definedAfterWithArguments: 1 2 3

Using only &:


definedAfterWithoutArguments
"&definedAfterWithArguments 1, 2, 3" generates a syntax error

Using bareword:
"definedAfterWithoutArguments" causes no action
"definedAfterWithArguments 1, 2, 3" generates a syntax error
rand( ) and srand( ) Functions
 The function rand( ) generates a floating-point scalar
value greater than or equal to 0 and less than 1.

 We can manually set the range of values that rand


returns by passing it a numeric argument. In this case,
rand returns a random value greater than or equal to 0
and less than the argument.

 The srand( ) function causes the computer to read its


system clock to obtain the value for the seed
automatically. This is the default behavior for srand.
1 #!usr/bin/perl
2 #
3 # Demonstrating function rand.
4
5 print "Random numbers produced by rand():\n";
6
7 for ( 1 .. 3 ) {
8 print " ", rand(), "\n";
9 }
10
11 print "\nRandom numbers produced by rand( 100 ):\n";
12
13 for ( 1 .. 3 ) {
14 print " ", rand( 100 ), "\n";
15 }
16
17 print "\nRandom integers produced by 1 + int( rand
(
186 ) ):\n";
19 for ( 1 .. 3 ) {
20 print " ", 1 + int( rand( 6 ) ), "\n";
21 }
Random numbers produced by rand():
0.76605224609375
0.387115478515625
0.648834228515625

Random numbers produced by rand( 100 ):


32.4371337890625
90.948486328125
83.7890625

Random integers produced by 1 + int( rand( 6 ) ):


6
4
1
1 #!/usr/bin/perl
2 #
3 # Seeding the random number generator.
4
5 # during each iteration, set seed to 1,
6 # then produce three random integers
7 for ( 1 .. 3 ) {
8 print "\n\nSetting seed to 1\n";
9 srand( 1 );
10
11 # produces same three values each time
12 for ( 1 .. 3 ) {
13 print " ", 1 + int( rand( 6 ) );
14 }
15 }
16
17 print "\n\nResetting seed\n";
18 srand(); # let system determine seed
19
20 for ( 1 .. 3 ) {
21
22 print "\n\nAfter seed has been reset\n";
23
24 for ( 1 .. 3 ) {
25 print " ", 1 + int( rand( 6 ) );
26 }
27
28 }
29
30 print "\n";
Setting seed to 1
1 4 2

Setting seed to 1
1 4 2

Setting seed to 1
1 4 2

Resetting seed

After the seed has been reset


2 4 6

After the seed has been reset


5 5 2

After the seed has been reset


4 5 5

What is the scope of a


variable?
Variable Scope
 Perl’s three scoping declaration makes it easy

 To create completely private variables (using my)


 To give selective access to global ones (using our)
 To provide temporary values to global variables (using
local)

 Ifmore than one variable is listed, the list must be


placed in parentheses.
Lexically Scoped Variables
 Perlprovides lexically scoped variables, often called
lexicals for short.
 Lexicals guarantee privacy.
 Lexicals
are totally hidden from the world outside their
immediately enclosing scope.
 Done using the my keyword.
Lexically Scoped Variables
 Lexicals are hidden from any subroutine called from
their scope. This is true even if the same subroutine
is called from itself or elsewhere. Thus, each
instance of the subroutine gets its own “scratchpad”
of lexical variables.
 Done using the my keyword.
 Every nested my produces a new variable.
Globally Scoped Variables
 Perlprovides us to have explicit globally scoped
variables, often called globals for short.
 Done using the our keyword.
 Our
provides access to global variables in the current
package.
 Placing an our declaration outside any brace-
delimited block, lasts through the end of the current
compilation unit.
 Repeated our declarations do not meaningfully nest,
they refer to the same global variable, irrespective of
nesting.
Dynamically Scoped Variables
 Using a local operator on a global variable gives it a
temporary value each time local is executed, but it
does not affect that variable’s global visibility.
 On reaching the end of the dynamic scope, this
temporary value is discarded.
 In short, dynamically scoped variables are global
variables that just happen to hold a temporary value
while that block is executing.
 If dynamically scoped variable holds a temporary
value and a function is called, the function accessing
the global variable sees the temporary value and not
the original value.
Variable Scope - Summary
 Keyword our explicitly defines a variable as a global
variable.

 Keyword my defines a lexically scoped variable.

 Keyword local defines a dynamically scoped


variable.
Recursive Calls
What is
recursion? Final value = 120
5! 5!
5! = 5 * 24 = 120 is returned
5 * 4! 5 * 4!
4! = 4 * 6 = 24 is returned
4 * 3! 4 * 3!
3! = 3 * 2 = 6 is returned
3 * 2! 3 * 2!
2! = 2 * 1 = 2 is returned

2 * 1! 2 * 1!
1 returned
1 1

a) Procession of recursive calls. b) Values returned from each recursive call.

Recursive evaluation of 5!.


1 #!/usr/bin/perl
2 #
3 # Recursive factorial subroutine
4
5 # call function factorial for each of the numbers
from
6 # 0 through 10 and display the results
7 foreach ( 0 .. 10 ) {
8 print "$_! = " . factorial( $_ ) . "\n";
9 }
10
11 # factorial recursively calculates the factorial of
the
12 # argument it receives
13 sub factorial
14 {
15 my $number = shift; # get the argument
16
17 if ( $number <= 1 ) { # base case
18 return 1;
19 }
20 else { # recursive step
21 return $number * factorial( $number - 1 );
22 }
23 }
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
Fibonacci Series
f( 3 )

return f( 2 ) + f( 1 )

return f( 1 ) + f( 0 ) return 1

return 1 return 0

Set of recursive calls to subroutine fibonacci.


1 #!/usr/bin/perl
2 #
3 # Recursive fibonacci function.
4
5 @sampleValues = (0, 1, 2, 3, 4, 5, 6, 10, 20, 30, 35);
6
7 # Calculate and print the fibonacci value of all the above values
8 foreach ( @sampleValues ) {
9 print "fibonacci( $_ ) = ", fibonacci( $_ ), "\n";
10 }
11
12 # fibonacci recursively calculates the fibonacci number
13 # of its integer argument
14 sub fibonacci
15 {
16 my $number = shift; # get the first argument
17
18 if ( $number == 0 or $number == 1 ) { # base case
19 return $number;
20 }
21
22 else { # recursive step
23 return fibonacci( $number - 1 ) +
24 fibonacci( $number - 2 );
25 }
26 }
fibonacci( 0 ) = 0
fibonacci( 1 ) = 1
fibonacci( 2 ) = 1
fibonacci( 3 ) = 2
fibonacci( 4 ) = 3
fibonacci( 5 ) = 5
fibonacci( 6 ) = 8
fibonacci( 10 ) = 55
fibonacci( 20 ) = 6765
fibonacci( 30 ) = 832040
fibonacci( 35 ) = 9227465

Can
Howwedo have
we resolve
two or name
more
subroutine conflict
with the?same name
Package or Namespace
 The package definition tells Perl that all variable and
subroutine definitions for the remainder of that file (or
until the next package statement) are in the specified
package (or namespace).
A package is defined using the key word package,
followed by the name of the package.
 Uses keyword require to tell Perl to locate the
package and add it to the program.
 The fully qualified name, in which the package and
the variable names are joined by the double colon
operator (::).
require Compiler Directive
 The require directive is used to load Perl libraries.

 require FirstPackage;

 The require directive takes the name of the Perl library


file and not the name associated with the package
keyword.
1 #!usr/bin/perl
2 # Name of the package is: FirstPackage.pm
3 # Our first package.
4
5 package FirstPackage; # name the
package/namespace
6
7 # define a package global variable
8 our $variable = "birthday";
9
10 # define a variable known only to this package
11 my $secret = "new year";
12
13 # subroutine that displays the values of
14 # the variables in FirstPackage
15 sub displayFirstPackageVariables
16 {
17 print "\$variable in
displayFirstPackageVariables
18 $variable, "\n"; = ",
19 print "\$secret in
displayFirstPackageVariables
20 $secret, "\n"; }= ",
44 }
1 #!usr/bin/perl
2 #
3 # Demonstrating packages.
4
5 # make FirstPackage.pm available to this program
6 require FirstPackage;
7
8 # define a package global variable in this program
9 our $variable = "happy";
10
11 # display values from the main package
12 print "From main package:\n";
13 print "\$variable = $variable\n";
14 print "\$main::variable = $main::variable\n";
15
16 # display values from FirstPackage
17 print "\nFrom FirstPackage:\n";
18 print "\$FirstPackage::variable = $FirstPackage::variable\n";
19 print "\$FirstPackage::secret = $FirstPackage::secret\n";
20
21 # use a subroutine in FirstPackage to display the
22 # values of the variables in that package
23 FirstPackage::displayFirstPackageVariables();
From main package:
$variable = happy
$main::variable = happy

From FirstPackage:
$FirstPackage::variable = birthday
$FirstPackage::secret =
$variable in displayFirstPackageVariables = birthday
$secret in displayFirstPackageVariables = new year

You might also like