www.Litecode.ru – Сборник рецептов для создания сайтов

Рекурсивная функция в perl

ГлавнаяPerl → Рекурсивная функция

Рекурсивная функция в языках программирования – такая функция, которая выполняет определенный блок операторов, вызывает сама себя и сохраняет вычисленные значения до тех пор, пока не выполнится определенное условие. Рекурсивные функции очень полезны для обработки данных, имеющих иерархическую структуру. С их помощью можно отобразить любое дерево элементов, будь это карта сайта или структура каталога, используя всего несколько строчек кода.

Например, чтобы отрисовать крошки сайта без “гвоздей”, от текущего url, нужно рекурсивно подняться наверх до страницы первого уровня. Флагом для выхода из процедуры будет отсутствие подчинения у очередной страницы, при этом все “дети” будут сохранены в результатах вычислений.

Правда, используя рекурсивные функции, стоит быть предельно осторожным. Одна, плохо отлаженная рекурсия, способна отправить в “аут” целый сервер, постепенно отъедая память. Для таких случаев, на UNIX-платформах админы обычно ставят ограничение для одного процесса по памяти.

Рассмотрим рекурсивную функцию в perl, на простом примере. Пусть дан массив:

my @array = (1,2,3,7,-5,9,4,-1,0,8);

В теории, он должен содержать только положительные числа. Наша задача написать рекурсивную функцию, которая будет проверять массив и возвращать индекс массива, если в значении недопустимый аргумент.

my @array = (1,2,3,7,-5,9,4,-1,0,8);

my $error = checker( \@array );

if ( $error ){
    print "Недопустимое значение в массиве с индексом $error!";
} else {
    print "Все ОК! Hello World...";
}

sub checker {

    my ( $ref , $index ) = @_; # принять ссылку на массив и текущий индекс
    $index ||= 0; # если текущий индекс не определен - присвоить '0'
    my @cut_array = @$ref; # разыменовать ссылку в массив
    
    my $current = shift @cut_array; # вытолкнуть первый член из массива
    
    if ( $current < 0 ){ # если отрицательное возвращаем ошибку
    
        return $index
        
    } elsif ( scalar @cut_array ){ # иначе вызываем себя еще раз
        
        $index++;
        checker( \@cut_array , $index );
        
    } else { # все ок, проверку прошли
    
        return undef
        
    }
}