Все задачи

Пути к файлам

29 Nov 2013
Read this article in English: here.

Программист написал функцию для подсчета уровней вложенности каталогов:

=head2 path_depth

Получает абсолютный путь к файлу/каталогу, возвращает его "глубину".
Обрабатывает пути в стиле Unix и Windows

/, a:\ --> 0
/bin, c:\program files --> 1
/etc/hosts --> 2
C:\WINDOWS\system32\drivers\etc\hosts --> 5
                                                          
=cut                                                      
                                                          
sub path_depth
{   
    my $path = shift;
    if ( $path =~ m{^/} ){
        # Unix
        $path =~ s!/+$!!g;
        $path =~ s!//+!/!g;
        return scalar(split '/', $path) - 1;
    } elsif ( $path =~ m{^.:} ) {
        # Windows
        $path =~ s!\\+$!!g;
        $path =~ s!\\+!\\!g;
        return scalar(split '\\', $path) - 1;
    } else {
        die "unknown format";
    }
}

Все ли хорошо с этой функцией? Как вы думаете?

Подсказка

Показать

Во-первых, этот код даже не компилируется.

Подсказка-2

Показать

С вот такой ошибкой: Trailing \ in regex m/\/. К чему бы это?

Подсказка-3

Показать

'\\' – это строка из одного символа.

Подсказка-4

Показать

Но даже если исправить Trailing \ in regex, все равно не все будет хорошо :(

Разоблачение

Показать

Проблема со split’ом в ветке для Windows, который получает первым параметром строку '\\'. Если split получает первым параметром строку, то строка интерполируется в регулярное выражение, и получается:

return scalar(split m{\}, $path) - 1;

Лучше всегда передавать split’у регулярное выражение в качестве первого аргумента: split m{\\}, $path – будет меньше подобных неприятных сюрпризов.

Кроме этого, функция неправильно определяет уровень корневого каталога в Unix: path_depth('/') возвращает -1 вместо 0.

Самый дотошный разбор проблем на этот раз прислал Кирилл kitt-vl. Браво!