Главная страница


ru.perl

 
 - RU.PERL ----------------------------------------------------------------------
 From : Valentin Nechayev                    2:5020/400     07 Aug 2002  09:52:39
 To : Pinsk CSM
 Subject : Re: Что такое //o?
 -------------------------------------------------------------------------------- 
 
 >>> Pinsk CSM wrote:
 
 PC> В чем же все-таки тайный смысл флага-модификатоpа re /o, о котоpом
 PC> документация Perl скpомно говоpит "o - compile only once"? Если же я плохо
 PC> искал, то укажите, пожалуйста, где найти более подpобную инфоpмацию.
 
 Гм. По-моему, информация была достаточно подробной. Попробую сказать
 другими словами.
 
 - Perl - императивный язык программирования. Это значит, что для него
 применимо понятие "поток управления" или "поток выполнения". Оно отражает
 последовательность выполнения действий. Hапример, написав
 
 $a = 1; $b = 1 + $a;
 
 ты получишь, что сначала выполнится первый оператор, а потом - второй.
 
 - Тот же поток выполнения справедлив и для оператора m//, как с опцией
 o, так и без него. В какой-то момент выполнение может дойти до данного оператора
 m//, потом оно пойдет дальше. Куда дальше - зависит от текста программы.
 Hо всегда можно говорить про: первое выполнение оператора; второе выполнение
 оператора; и так далее, даже если второго или даже первого выполнения не
 происходит.
 
 - Если шаблон поиска константный - не содержит переменных - то он компилируется
 во внутреннее представление (фактически, таблица переходов автомата) при
 чтении программы перед выполнением. Компиляция шаблона - дорогая операция,
 и делать ее каждый раз было бы очень сильным замедлением.
 
 - Если шаблон поиска содержит переменные, он компилируется каждый раз, как
 поток выполнения проходит через этот оператор m//, перед применением
 скомпилированной формы. Это дорого, но иногда это нужно.
 Хотя часто легче обойтись другими вариантами - например, скомпилировав
 на ходу безымянную подпрограмму.
 
 - Можно избавиться от компиляции шаблона каждый раз, добавив опцию 'o'.
 В результате, он скомпилируется один раз при первом исполнении оператора
 m//, _зафиксировав в себе те значения переменных, что были при первом
 выполнении_. Я подчеркнул ключевые слова.
 
 Где это нужно и полезно? Hапример, если переменные в шаблоне - берутся
 при запуске из конфигурации. Они могут меняться в конфигурации - то есть
 между выполнениями программы - но во время одного выполнения используются
 уже прочтенные значения.
 
 Ключевые слова в описанном:
 - Поток выполнения. Порядок исполнения операторов - какой раньше, какой
 позже, какой первым, и т.д.
 - Первое исполнение оператора.
 
 Остановись здесь и подумай над порядком исполнения операторов.
 Если непонятно - ой, тогда, боюсь, надо учить программирование заново...
 (nothing personal. очень многие проходят на интуиции эти моменты, не осознавая
 их, а потом спотыкаются на нестандартных ситуациях)
 
 PC> +--------------------------------------------+
 PC> | Пpимеp 10.5. Флаг o в опеpации m//         |
 PC> +--------------------------------------------+
 
 Я его немного переделаю:
 
 #!/usr/bin/perl
 @pattnlist = ("a+", "b+");
 while(<STDIN>) {
   $line = $_; chomp $line;
   foreach $pattn (@pattnlist) {
     $line =~ m/$pattn/o;
     print "\$pattn=$pattn \$& = $&\n";
   }
 }
 
 - на каждую строку будет выводиться результат для двух (для простоты)
 шаблонов. Запускаем:
 
 08:47:21:netch@iv:~/tmp>perl 5.pl
 a
 $pattn=a+ $& = a
 $pattn=b+ $& = a
 b
 $pattn=a+ $& =
 $pattn=b+ $& =
 ab
 $pattn=a+ $& = a
 $pattn=b+ $& = a
 
 Теперь убираю o:
 
 08:47:56:netch@iv:~/tmp>perl 5.pl
 a
 $pattn=a+ $& = a
 $pattn=b+ $& =
 b
 $pattn=a+ $& =
 $pattn=b+ $& = b
 ab
 $pattn=a+ $& = a
 $pattn=b+ $& = b
 
 Различие четко видно.
 
 PC> Этот скpипт одинаково добpосовестно пеpебиpает все обpазцы из списка "a+",
 PC> "b+", "c+" и "d+", не глядя ни на флаги, ни на модификатоpы /o, т.е.
 PC> pезультат одинаков всегда и везде: что под Win, что под Linux.
 
 Это ты его все-таки плохо кормил входными значениями;)
 Hо в том варианте, как я написал, будет показательнее.
 
 P.S. Для s/// то же самое что для m// - тоже компиляция каждый раз или один раз.
 /netch
 --- ifmail v.2.15dev5
  * Origin: Dark side of coredump (2:5020/400)
 
 

Вернуться к списку тем, сортированных по: возрастание даты  уменьшение даты  тема  автор 

 Тема:    Автор:    Дата:  
 Re: Что такое //o?   Valentin Nechayev   07 Aug 2002 09:52:39 
 Re: Что такое //o?   Maxim Goncharov   07 Aug 2002 15:52:54 
Архивное /ru.perl/7368d2bab5b8.html, оценка 2 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional