Xpoint
   [напомнить пароль]

Программирование::Perl::Основы - F.A.Q.

Как правильно задавать вопросы?
Я хочу изучать Perl. Какие книги или ресурсы интернета мне помогут?

On-line ресурсы, посвященные Perl:

Книги:

Ссылки на статьи и книги on-line:

Рассылки:

Ссылки на F.A.Q. Perl-форумов
Почему скрипт, написаный в редакторе под Windows, не запускается под Unix?

Большинство редакторов под Windows используют комбинацию символов CR LF как перевод строки, в то время как под Unix используется только LF. Сам Perl игнорирует символ CR, но при запуске скрипта из первой строки файла считывается путь к интерпретатору Perl и туда попадает этот лишний символ. Соответственно интерпретатор не находится, отсюда и ошибка. Если открыть скрипт редактором vi, символ CR показывается как ^M. Достаточно удалить его из первой строки файла.

Как удалить элемент массива?

Пусть нужно удалить элемент массива @array с индексом $index.

Способ 1 - функция splice(массив, смещение, длина)

    splice(@array, $index, 1);

Способ 2 - создание нового массива

В Perl есть очень гибкие возможности инициализации массивов. Благодаря этому можно одной строкой создать копию массива @array без элемента $index:

    @array=(@array[0..$index-1], @array[$index+1..$#array]);

Учтите, что для подобной инициализации Perl по всей вероятности создаст еще и промежуточные копии массива, что приведет к дополнительному расходу памяти.

Функция delete

При прочтении документации можно подумать, что задачу можно решить и функцией delete:

    delete($array[$index]);

Данный код не удаляет элемент массива, а удаляет лишь его значение, оставляя элемент массива не инициализированным. Равнозначная операция:

    $array[$index] = undef;
Как перехватить ошибки в скрипте?

Способ 1: глобальный обработчик ошибок

Автор ответа - Андрей Новиков

Для перехвата ошибок можно установить свой обработчик сигнала DIE:

    BEGIN {
        $SIG{__DIE__} = sub {
            my $text = shift;

            print "Content-type: text/plain\n\n";
            print "ERROR: $text\n";

            exit(0);
        };
    }

    ...

    die "Здесь произошла ошибка!";

    ...

По тому же принципу работает модуль CGI::Carp, вывод ошибок на браузер включается так:

    CGI::Carp qw(fatalsToBrowser);

Аналогично можно с помощью обработчика $SIG{__WARN__} перехватывать предупреждения, которые выдает скрипт (к примеру функцией warn), и писать их в собственный лог-файл.

Способ 2: перехват ошибок в куске кода

Блок eval позволяет перехват ошибок в определённом куске кода и последущую их обработку:

    eval {
        ...

        die "Здесь произошла ошибка!";

        ...
    };
    if ($@) {
        print "Content-type: text/plain\n\n";
        print "ERROR: $@\n";

        exit(0);
    }

Предупреждение: Начиная с Perl 5.6 приоритет глобального обработчика ошибок $SIG{__DIE__} стал выше приоритета блока eval. При наличии глобального обработчика локальный перехват ошибок игнорируется. Поэтому мешать эти два спрособа перехвата ошибок не рекомендуется.

Как получить информацию о файле (время создания, изменения и т.п.)?

Способ 1 - функции -X

    if (-e $filename) { print "Файл существует.\n"; }
    if (-z $filename) { print "Файл существует и он пустой.\n"; }
        
    if (-r $filename) { print "У меня есть право на чтение файла.\n"; }
    if (-w $filename) { print "У меня есть право на изменение файла.\n"; }
    if (-x $filename) { print "У меня есть право на выполнение файла.\n"; }
    if (-o $filename) { print "Я владелец файла.\n"; }
        
    if (-f $filename) { print "$filename - это обычный файл.\n"; }
    if (-d $filename) { print "$filename - это каталог.\n"; }
    if (-l $filename) { print "$filename - это символическая ссылка.\n"; }
    if (-p $filename) { print "$filename - это FIFO.\n"; }
    if (-S $filename) { print "$filename - это сокет.\n"; }
    if (-b $filename) { print "$filename - это блок-ориентированное спец. устройство.\n"; }
    if (-c $filename) { print "$filename - это символьное спец. устройство.\n"; }
    if (-t $filename) { print "Файловый манипулятор открыт для терминала.\n"; }

    if (-u $filename) { print "У файла установлен бит setuid\n"; }
    if (-g $filename) { print "У файла установлен бит setgid\n"; }
    if (-k $filename) { print "У файла установлен бит запрета (бит-липучка)\n"; }

    if (-T $filename) { print "Это текстовый файл.\n"; }
    if (-B $filename) { print "Это двоичный файл.\n"; }

    $size = -s $filename;
    print "Размер файла: $size.\n"; }

    $modification_time = int(-M $filename);
    print "Со времени последнего изменения файла прошло $modification_time дней.\n";

    $access_time = int(-A $filename);
    print "Со времени последнего чтения файла прошло $access_time дней.\n";

    $ctime = int(-C $filename);
    print "Со времени последнего изменения файлового дескриптора прошло $ctime дней";

Способ 2 - функция stat

($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
 $atime, $mtime, $ctime, $blksize, $blocks) = stat($filename);

($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
 $atime, $mtime, $ctime, $blksize, $blocks) = stat(FILEHANDLE);

stat возвращает список из 13-ти элементов. Вот их значение:

    0 $dev      номер устройства, на котором расположен файл
    1 $ino      номер файлового дескриптора
    2 $mode     флаги файла (права, setuid и прочее)
    3 $nlink    количество (жестких) ссылок на файл
    4 $uid      числовой идентификатор пользователя владельца файла
    5 $gid      числовой идентификатор группы владельца файла
    6 $rdev     идентификатор устройства (только спец. файлов)
    7 $size     размер файла в байтах
    8 $atime    время последнего чтения файла в секундах с 1.1.1970
    9 $mtime    время последнего изменения файла в секундах с 1.1.1970
   10 $ctime    время последнего изменения файлового дескриптора в секундах с 1.1.1970
   11 $blksize  предпочтительный размер блока в файловой системе
   12 $blocks   количество блоков, зарезервированых на данный момент

Способ 3 - Модулъ File::stat

Модуль File::stat обеспечивает удобный доступ к результатам функции stat по именам:

    use File::stat;
    $st = stat($filename) or die "No $filename: $!";
    $size = $st->size;
    print "Размер файла $filename - $size\n";
Как получить значение переменной по имени?

Как получить значение переменной, имя которой записано в другой переменной?

Пример 1:

    $var1 = 'lalala';
    $var2 = 'var1';
    $result = $$var2;

Значение $result будет - "lalala"

Пример 2 (посложнее):

 
    $complex_var = 'lalala';
    $simplex_var = 'hohoho';
    $modifier = 'complex';
    $result = ${$modifier.'_var'};

Значение $result опять будет "lalala"

Как обезопасить текст, который пользователь вводит в форму, чтобы его можно было показывать на странице?

Если текст, который вводит пользователь, просто вставить в страницу, то там может оказаться что-то вроде <script>alert('Visit my homepage: http://pupkin.ru/')</script>. Для того, чтобы это не произошло, следует при получении данных из формы или при их отображении на странице преобразовать знаки, имеющие значение в HTML:

    $text =~ s/&/&amp;/g;
    $text =~ s/</&lt;/g;
    $text =~ s/>/&gt;/g;
    $text =~ s/"/&quot;/g;
Powered by POEM™ Engine Copyright © 2002-2005