Perl | Recursive Subroutines
Last Updated :
21 May, 2024
Prerequisite: Recursion in Perl
Recursive means about or using a rule or procedure that can be applied repeatedly. It is the process of defining a function or calculating a number by the repeated application of an algorithm. Recursive Subroutine is a type of subroutine that calls itself as part of its execution or is in a potential cycle of function calls. Perl provides us with the flexibility to use subroutines both iteratively and recursively.
A simple example showing the use of a recursive subroutine in Perl would be that calculating the factorial of a number.
Example:
Perl
#!/usr/bin/perl
# Perl Program to calculate Factorial
sub factorial
{
my $n = $_[0];
# checking if that value is 0 or 1
if ($n == 0 || $n == 1)
{
return 1;
}
# Recursively calling the function with the next value
# which is one less than current one
else
{
return $n * factorial($n - 1);
}
}
# Driver Code
$n = 7;
# Function call and printing result after return
print "Factorial of a number $n is ", factorial($n);
OutputFactorial of a number 7 is 5040
Traversing a Directory Tree
Traversing a directory tree means to iterate over or to print each file and sub-directories within a root directory. The directory tree is a representation of the sub-directories and files within sub-directories and other files within the directory in the form of a tree denoting the parent-child relationship between these directories and respective files.
Both Unix and Windows systems organize file directories into a tree structure. Although in Perl, traversing a directory tree or walking a directory tree can be done both iteratively and recursively, but we often use the later one when the number of files or sub-directories inside our root folder is very large. This is because of the fast and less number of lines of code written in recursive function in comparison to an iterative one. The later is used when the corresponding number of files are less in number.
We'll use File::Find to traverse the file system iteratively and collect the filenames.
Syntax :
use File::Find;
find(\&wanted, @directories_to_search);
sub wanted { ... }
use File::Find;
finddepth(\&wanted, @directories_to_search);
sub wanted { ... }
use File::Find;
find({ wanted => \&process, follow => 1 }, '.');
Example:
Perl
#!/usr/bin/perl
use strict;
use warnings;
use File::Find::Rule;
use File::Basename qw(basename);
my $loc = "C:\Users\GeeksForGeeks";
my $file = 'final.txt';
my $expected = <STDIN>;
chomp $expected;
open(my $fh, '<', $expected) or
die "Could not open '$expected' $!\n";
open(my $out, '>', $file) or
die "Could not open '$file' $!\n";
my @paths = File::Find::Rule->file->name('*.pdf')->in($loc);
my @files = map { lc basename $_ } @paths;
my %case = map { $_ => 1 } @files;
print $out "This file has been copied from ($loc)$file:\n";
while (my $name = <$fh>)
{
chomp $name;
if ($case{lc $name})
{
print "$name found\n";
}
else
{
print $out "$name\n";
}
}
close $out;
close $fh;
Output: Source file gets copied to the destination file

In the coming section, we will discuss the Recursive traversal of the root directory.
Recursively Traversing a Directory Tree
The problem with the iterative solution of traversal apart from its slow speed and more lines of code is the fact that all the sub-directories within the root directory must have the same orientation and the same number of files within them. Otherwise, the traversal can become a complex task. Recursive solution plays a better role in overcoming the problem with the iterative solution.
Example (Recursive):
Perl
#!/usr/bin/perl
# Perl recursive Program to walk
# through a directory tree
use strict;
use warnings;
use 5.010;
my $loc = shift || '.';
# Calling walk subroutine with
# the location of the root directory
walk($loc);
# Subroutine definition
sub walk
{
my ($case) = @_;
# If case is not a directory itself
return if not -d $case;
# If case is a directory
opendir my $dh, $case or die;
while (my $sub = readdir $dh)
{
next if $sub eq '.' or $sub eq '..';
say "$case/$sub";
walk("$case/$sub");
}
close $dh;
return;
}
Output :

The above code will let you loop over each file in the root directory and all the sub-directories present in the root directory along with the files and directories within these sub-directories.
Top Down Approach
The top-down approach basically divides a complex problem or algorithm into multiple smaller parts (modules). These modules are further divided until the resulting module is a program which can not be further decomposed.
Here, we first initialize a variable called $case which keeps hold of the file or the directory being iterated or looped over. Then if it's a file, then the function simply prints its name and loop over to next file or directory or else if the $case is a directory, then it calls the subroutine again with the directory location as the current directory location and then loop over all the files and sub-directories within that directory. After the completion of the inner function, the pointer returns back to the location of the outer directory and print its name and then moves to the next file or the directory present in the root directory. This is actually a typical Top-Down Approach used in Perl for traversing or walking over a directory tree.
Example:
Perl
use strict;
use warnings;
use 5.010;
my $loc = shift || '.';
walk($loc);
sub walk
{
my ($case) = @_;
say $case;
return if not -d $case;
opendir my $dh, $case or die;
while (my $sub = readdir $dh)
{
next if $sub eq '.' or $sub eq '..';
walk("$case/$sub");
}
close $dh;
return;
}
Output:

The code explained in the section Recursively traversing a directory tree is an example of the Top-Down Approach used in Perl.
Note : The above Output image shows a small portion of the complete output as there are a lot of files and subdirectories inside the root directory. This code works fine for folders and directories with a small number of sub-directories.
Recursive Function
A recursive function has the following general form:
Function( arguments ) {
if a simple case, return the simple value // base case / stopping condition
else call function with simpler version of problem
}
Example:
Perl
#!/usr/bin/perl
# Perl Program to calculate Factorial
sub myfunc
{
my $n = $_[0];
# checking if that value is
# greater than 0 or not
if ($n <= 0)
{
print "Now, You are on GFG portal.\n";
}
# Recursively calling function with
# the next value which is one less
# than current one
else
{
print "$n\n";
myfunc($n - 1);
}
}
# Driver Code
# Function call
myfunc(3);
Output:

For a recursive function to stop calling itself we require some type of stopping condition. If it is not the base case, then we simplify our computation using the general formula. A recursive function has two major parts. The first one checks for some condition and returns if that condition was met. This is called the halting condition, or stop condition. Then at some later point in the function, it calls itself with a different set of parameters than it was called earlier.
Why recursion preferred over iteration ?
- It comes with the positives of writing cleaner and simpler short code.
- It is also efficient in terms of time if used with memorization
- Performs better in solving problems based on tree structures.
Similar Reads
Perl | References to a Subroutine
Prerequisite: Perl references Declaring References to a Subroutine In Perl, a reference is, exactly as the name suggests, a reference or pointer to another object. References actually provide all sorts of abilities and facilities that would not otherwise be available and can be used to create sophis
6 min read
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 b
7 min read
Perl | Multiple Subroutines
Prerequisite: Perl | Subroutines or Functions A Perl function or subroutine is a group of statements that together perform a specific task. In every programming language user want to reuse the code. So the user puts the section of code in function or subroutine so that there will be no need to write
3 min read
Recursion in Perl
Recursion is a mechanism when a function calls itself again and again till the required condition is met. When the function call statement is written inside the same function then such a function is referred to as a recursive function.The argument passed to a function is retrieved from the default a
3 min read
Subroutines in COBOL
Subroutines in COBOL are small programs that are compiled independently but cannot be run directly. Cobol subroutine is a small program that can be compiled independently but cannot be run directly. There are two types of COBOL Â subroutines- internal subroutines and the external subroutines Call Ver
3 min read
Perl | References
In Perl, we use variables to access data stored in a memory location(all data and functions are stored in memory). Variables are assigned with data values that are used in various operations. Perl Reference is a way to access the same data but with a different variable. A reference in Perl is a scal
4 min read
Perl | Subroutines or Functions
A Perl function or subroutine is a group of statements that together perform a specific task. In every programming language user want to reuse the code. So the user puts the section of code in function or subroutine so that there will be no need to write code again and again. In Perl, the terms func
2 min read
Recursive Formula
A recursive function is a function that defines each term of a sequence using the previous term i.e., The next term is dependent on one or more known previous terms. Recursive function h(x) is written as,h(x) = a0h(0) + a1h(1) + a2h(2) + ... + ax - 1h(x - 1)where, ai ⥠0i = 0, 1, 2, 3, ... ,(x - 1)T
4 min read
Perl | Passing Complex Parameters to a Subroutine
Prerequisite: Perl | Subroutines or Functions A Perl function or subroutine is a group of statements that together perform a specific task. In every programming language, the user wants to reuse the code. So the user puts the section of code in a function or subroutine so that there will be no need
4 min read
Dart - Recursion
Recursion in any programming language means a function making a call to itself. It is used to solve large complex problems by breaking them into smaller subproblems. Dart also implements recursion similarly. In a recursive function, the function calls itself repeatedly until a base condition is reac
3 min read