Dhruv Tyagi Dhruv Tyagi - 3 months ago 7
Perl Question

Is it possible to call a function from itself?

In my Perl code I have to call the

ls
function and check it if any child is there. Then I have to call the same function again otherwise perform some action.

For example

# call ls Method

sub check_ls {

$folder = $foo->ls();
$length = @listing;

if ( $length > 1 ) {

#do something
}
elsif ( $length == 1 ) {
check_ls();
}
}


==================================================

Question-2:


can anyone describe/edit my below code

my $foo=cms::folder_entry->new(); #create a new object of folder_entry class
$root_entry_id =$foo->new_root_folder(folder_name=>'test_root_timestamp'); #now i call the new_root_folder and in return i got the id
my $root = folder_entry_id->new($root_entry_id); #now again create a new object through passing $root_entry_id parameter


or the below statement is the correct statement?

my @listing = $root->$foo->ls();


Please edit my Comment if i am wrong in secound Question

Answer

This is a perfectly valid approach. It's called recursion, and it's often used to traverse tree-like structures.

It's important to include a condition that will end the recursion.

However your code looks like it's not going to work. You are using global variables. You should be using lexicals declared using the my keyword inside of your function, and you need to pass in the current state into the recursion.

Consider this example of calculating factorials.

sub fac {
    my $number = shift;

    return 1 if $number == 1;
    return $number * fac($number - 1);
}

print fac(5);

It will go all the way into the recursion down to the deepest level. Then it will calculate backwards up the recursion tree. In each call, the lexical variables will be scoped, so they don't clash or get overwritten.

Look at this rewrite with debug output.

sub fac {
    my $number = shift;

    print "in: $number\n";

    return 1 if $number == 1;

    my $return = $number * fac($number - 1);
    print "out: $return\n";

    return $return;
}


print fac(5);

Here is the output.

in: 5
in: 4
in: 3
in: 2
in: 1
out: 2
out: 6
out: 24
out: 120
120

If you run a Perl that is at least version 5.16, you can use the __SUB__ keyword instead of the name of your sub inside of that same sub. It returns a reference to the current subroutine. That way, you can even build recursive anonymous subs. You do need to turn it on with use feature 'current_sub' or use v5.16 though.

use feature 'current_sub';

sub fac {
    my $number = shift;

    print "in: $number\n";

    return 1 if $number == 1;

    my $return = $number * __SUB__->($number - 1);
    print "out: $return\n";

    return $return;
}

Also add the use strict and use warnings 'all' pragmas to your code to enforce stricter rules that will make it easier to debug your code.

Comments