Perl | Scope of a Subroutine

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:

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


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



filter_none

edit
close

play_arrow

link
brightness_4
code

#!/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
}

chevron_right


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:

filter_none

edit
close

play_arrow

link
brightness_4
code

#!/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
}

chevron_right


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



filter_none

edit
close

play_arrow

link
brightness_4
code

#!/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";
}

chevron_right


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:

filter_none

edit
close

play_arrow

link
brightness_4
code

#!/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";
}

chevron_right


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:

filter_none

edit
close

play_arrow

link
brightness_4
code

#!/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";
}

chevron_right


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.



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.




Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.