Open In App

Perl | Scope of a Subroutine

Last Updated : 19 Jul, 2019
Improve
Improve
Like Article
Like
Save
Share
Report

Subroutines in Perl, are reusable unit of code. It is a dynamic concept. Functions and subroutines are the two terms that can be used interchangeably. If you want to be strict on the semantics, small pieces of named blocks of code that accept arguments and return values are called subroutines. The built-in subroutines in Perl are usually referred to as Perl’s functions because they provide additional functionality. A subroutine created as part of a class definition is called a method.
Subroutines can be called from just about anywhere, and return control to the point of the call when they finish executing. They can be called with zero or more arguments and may return zero or more results.

Like variables, subroutines can either be just declared (without defining the work they do) or declared and defined. To simply declare a subroutine, we use one of the following forms:

Syntax :
sub SUB_NAME
sub SUB_NAME PROTOTYPE
sub SUB_NAME ATTRIBUTES
sub SUB_NAME PROTOTYPE ATTRIBUTES

where SUB_NAME is the name of the subroutine being created, PROTOTYPE is the prototype for the arguments that the subroutine should expect when called, and ATTRIBUTES is a list of attributes that the subroutine exhibits. The PROTOTYPE and ATTRIBUTES arguments are optional.

NOTE: Subroutines can be named or can be anonymous. Perl allows creating anonymous subroutines also i.e. subroutines without a name. This can be done by omitting the NAME component. However, you can’t create an anonymous subroutine without a definition (Perl has no way of later attaching the definition without knowing the subroutine’s name). You will also need to assign the subroutine to a scalar variable in order to call it later.

Example:




# Perl program to demonstrate
# simple subroutine
  
sub message    # Declared subroutine 
    print "Hello!\n";   # Body of subroutine
}
  
$message = message;    # Calling subroutine


Output:

Hello!

Subroutine Scope

The idea of scope deals with the area in which a variable or subroutine is defined and can be utilized and accessed by other parts of the program. Perl subroutines supports mainly two types of scopes- Lexical, and Global.

Just like variables, subroutines also live in a particular scope, whether it’s lexical or global scope.

Global Scope
 
The subroutines and variables are Globally scoped if it can be used everywhere in the entire program, unless overridden by a lexically scoped subroutine and variable respectively, of the same name. Global variables are available to all the different functions and libraries of the program, although they are required to be loaded before use for each function separately.

Syntax:
sub Dummy ($param1, $param2) { . . . }

These subroutines can access globally scoped variables only. Most built-ins in Perl are globally scoped.

Example




#!/usr/bin/perl
  
# Subroutine definition
sub Max 
{
      
    # get total number of arguments passed.
    $n = scalar(@_);     # local scoped 
    $max = 0;             # local scoped
      
    foreach $item (@_
    {
        if ($item > $max)
        {
            $max = $item;
        }
    }
    print "Max from the given numbers : $max\n";
}
  
# Subroutine call
Max(10, 20, 30, 40, 50, 100); # called globally
  
$user_input = "GeeksforGeeks";
if (length($user_input) >= 7)
{
    Max(45, 56, 78, 76, 26, 90);     # called locally
}


Output:

Max from the given numbers : 100
Max from the given numbers : 90

Lexical Scope
 
The subroutines can also be Lexical just as variables. Lexical subroutines are those which are declared and defined within a function or within an If-Else condition and can only operate within that scope. Outside the scope they are not recognized by other parts of the program. Lexical subroutines can access global as well as local variables (defined within its scope). Lexical subroutines are called just like a normal subroutine:

Syntax:
if $condition1
{
my sub sub1 ($param1, $param2)
{
. . .
}

sub1($arg1, $arg2); # Calling within the scope
}

# sub1($arg3, $arg4); # error – Calling outside scope

The first call to sub1 is fine, but the second would be a compile-time error because sub1 has been called outside it’s scope of definition.

Example:




#!/usr/bin/perl
  
$user_input = "Geeks";
  
if (length($user_input) >= 7) 
{
    # Subroutine definition local to IF block
    sub Max 
    {
          
        # get total number of arguments passed.
        $n = scalar(@_);     # local scoped 
        $max = 0;             # local scoped
          
        foreach $item (@_
        {
            if ($item > $max
            {
                $max = $item;
            }
        }
        print "Max from the given numbers : $max\n";
    }
  
    Max(45, 56, 78, 76, 26, 90);     #called locally
}
else 
{
  
    # Subroutine definition local to ELSE block
    sub Max 
    {
          
        # get total number of arguments passed.
        $n = scalar(@_);     # local scoped 
        $max = 0;             # local scoped
          
        foreach $item (@_
        {
            if ($item > $max
            {
                $max = $item;
            }
        }
        print "Max from the given numbers : $max\n";
    }
  
    Max(4, 6, 17, 37, 6, 9);     #called locally
}


Output:

Max from the given numbers : 37

Use of my and local

my and local in Perl subroutines are used to limit the scope of a variable or a subroutine in the program. Limiting the scope means to limit the area from which the respective variable can be accessed.
 
Effects of my
 
All the variables in Perl are by default global variables, which means the compiler can access them from anywhere in the program. But private variables called lexical variables can also be created using my operator.
The my keyword declares a variable to be scoped within the current block. For the duration of the block, the new variable will take precedence over any previously scoped variable. When the block ends, the variable goes out of scope.

Example




#!/usr/bin/perl
  
my $string = "GeeksforGeeks";
print "$string\n";
myfunction();   # function call
print "$string\n";
  
# Subroutine 1 definition
sub myfunction 
{
      
    # Private variable for function
    my $string = "GFG";
    print "Inside myfunction $string\n";
    mysub();
}
  
# Subroutine 2 definition
sub mysub
{
    print "Inside mysub $string\n";
}


Output:

GeeksforGeeks
Inside myfunction GFG
Inside mysub GeeksforGeeks
GeeksforGeeks

The moment the block terminates, the variable effectively disappears from view. We can’t access a variable declared with my from outside of the block within which it’s defined.
It also means that variables declared with my within a module are not accessible outside of that module (since the module is a single block), even when called upon explicitly by using $MyModule::string.

 
Effects of local
 
The local variable is really a dynamically scoped variable. It effectively creates a copy of a global variable within the current scope. It operates just like a lexically scoped variable; its effects disappear when the variable goes out of the current scope, with the variable returning to its original value instead of simply disappearing.

Example:




#!/usr/bin/perl
  
$string = "GeeksforGeeks";
print "$string\n";
myfunction();
print "$string\n";
  
# Subroutine 1 definition
sub myfunction 
{
      
    # Private variable for function
    local $string = "GFG";
    print "Inside myfunction $string\n";
    mysub();
}
  
# Subroutine 2 definition
sub mysub
{
    print "Inside mysub $string\n";
}


Output:

GeeksforGeeks
Inside myfunction GFG
Inside mysub GFG
GeeksforGeeks

Note: The value of a variable modified using local is consistent for all functions called from the block in which the variable has been localized.

So, local just suspends the global variable and creates a temporary scope for the global variable whereas my defines a new lexical variable within the scope it is defined and this variable gets destroyed once we come outside of the scope of its definition.
 
Effects of our
 
Perl supports another scoping declaration that enables us to create a selectively global variable, using keyword our. The our declaration is a relatively new invention, and it allows you to declare a variable as being global and potentially usable by any other subroutine defined in your script.
Both my and our are examples of lexically scoped variables. The only difference is in the level at which the lexical scope is applied.

Example:




#!/usr/bin/perl
  
our $string = "GeeksforGeeks";
print "$string\n";
myfunction();
print "$string\n";
  
# Subroutine definition
sub myfunction 
{
      
    # Private variable for function
    our $string = "GFG";
    print "Inside myfunction $string\n";
}


Output:

GeeksforGeeks
Inside myfunction GFG
GFG

Using our within a function, or indeed any form of nesting within any block, on the same variable has no effect. It always refers to the same global variable. The use of our on a variable declared with my will have no effect.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads