Форум программистов, компьютерный форум, киберфорум
Perl: Web
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/4: Рейтинг темы: голосов - 4, средняя оценка - 4.50
166 / 164 / 27
Регистрация: 20.04.2010
Сообщений: 607
1

Объяснить работу функции

17.03.2014, 18:54. Показов 755. Ответов 3
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день.

Решил поизучать на досуге Perl и столкнулся с проблемой.

Есть у меня две функции:
Perl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
sub getAvarageTime
{
    if($_[1]=~ m/^\s*execute\s*(.*)/gi)
    {
                #Выполняет что то.
        return 1;       
    }
    else
    {
        return -1;
    }   
}
 
sub getExplain
{   
    if($_[1]=~ m/^\s*execute\s*(.*)/gi)
    {       
        #Выполняет что то.
        return "ok";            
    }
    else
    {
        return "no";
    }   
}
И собственно вызов их в коде.
Perl
1
2
3
4
5
6
7
8
sub main
{
        my $query; #некая строка.
        my $dbh2;
 
        getAvarageTime($dbh2,$query);
    getExplain($dbh2,$query);
}
Все лишнее выкинул, да бы не было слишком много букв.

Собственно проблема: только в одной функции выражение $_[1]=~ m/^\s*execute\s*(.*)/gi возвращает true, во второй false.
Почему?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.03.2014, 18:54
Ответы с готовыми решениями:

Объяснить работу функции
Может кто объяснить работу функции void zagalovok() { Node *t; head=new Node(); ...

Работа функции qsort - объяснить работу функции
#include<iostream> #include<cstdlib> int mysort(const void *arg1, const void *arg2); int main()...

Объяснить работу побитовой операции в функции
Функция из книги Кернигана. не могу понять её. про инверсию я понял, а вот каким образом мы создаем...

Объяснить работу функции, вычисляющей сумму цифр числа
Добрый вечер. Наткнулся на код, который работает , но не понял как работает функция getSumOfNumber...

3
5989 / 1998 / 323
Регистрация: 10.12.2013
Сообщений: 6,882
18.03.2014, 05:56 2
Собственно проблема: только в одной функции выражение $_[1]=~ m/^\s*execute\s*(.*)/gi возвращает true, во второй false.
Почему?
Вопрос получился шикарный,
если рассматривать этот пример через призму
"Влияние стиля прграммирования на возникновение странных ошибок"

я упростил стилистически вышеприведённый код, чтобы было пояснее.

Perl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/perl -w
use strict;
 
sub eee {
        my $query = shift;
        return ( $query =~ m/execute\s*(.*)/ig )
                ? "EEE-ok ($1) \n"
                : "EEE-no \n";
}
 
sub fff {
        my $query = shift;
        return ( $query =~ m/execute\s*(.*)/ig )
                ? "FFF-ok ($1) \n"
                : "FFF-no \n";
}
 
my $query = "execute zhoppa s ruchkoj";
 
print "eee call result = ", eee($query);
print "fff call result = ", fff($query);
в таком виде, он отработает корректно:
Кликните здесь для просмотра всего текста

eee call result = EEE-ok(zhoppa s ruchkoj)
fff call result = FFF-ok(zhoppa s ruchkoj)


то есть, когда я стилистически исправлял,
я механически заменил конструкцию номерных аргументов списка @_,
на рекомендованную в смысле правильного стиля my $arg1 = shift;

вернём авторский вариант:
Perl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/perl -w
use strict;
 
sub eee {
     
        return ( $_[0] =~ m/execute\s*(.*)/ig )
                ? "EEE-ok ($1) \n"
                : "EEE-no \n";
}
 
sub fff {
       
        return ( $_[0] =~ m/execute\s*(.*)/ig )
                ? "FFF-ok ($1) \n"
                : "FFF-no \n";
}
 
my $query = "execute zhoppa s ruchkoj";
 
print "eee call result = ", eee($query);
print "fff call result = ", fff($query);
и тут же получаем:
Кликните здесь для просмотра всего текста
eee call result = EEE-ok(zhoppa s ruchkoj)
fff call result = FFF-no


Теперь убираем модификатор /g из регулярного выражения m/^\s*execute\s*(.*)/gi ,
( он всё равно не нужен, потому что жадный поиск схавает по / (.*) / всё до конца строки за один присест )

и опять всё становится нормально:
Кликните здесь для просмотра всего текста

eee call result = EEE-ok(zhoppa s ruchkoj)
fff call result = FFF-ok(zhoppa s ruchkoj)


Интрига достигает апогея и в этот волнующий момент наш простой и скромный программист Перл
вспоминает, что выражение $_[n] - это простой alias на собственно переданный аргумент
( или по С-ишному ссылка -> изменив $_[n], мы изменим и сам аргумент ),
а вот выражение $arg1 = shift честно копирует аргумент в $arg1;

одновременно с этим наш скромняга-герой вспоминает, что в скалярном контексте поиск с модификаторм /g
последовательно возвращает каждый следующий найденный шаблон, двигая указатель, который можно, например,
извлечь с помощью функции pos( x ), а поскольку $_[0] в функциях eee() и fff() указывает на одно и то же место и собственно рег. выражение одно и то же, я намекаю на то, что оптимизатор применил шаблон согласно модификатору /g
к одному и тому же выражению 2раза: в первый раз вернулась жопа с ручкой, а второй раз не вернулось ничего, потому что всё уже было съедено и механизм рег. выражений закончил работу.

можно трактовать это как ошибку реализации или же как фичу, но получается, что Д.Конвэй прав -
если писать стилистически красиво, то на такие фичи никогда и не нарвёшься.

Добавлено через 13 минут
а оптимизатор я обвиняю потому,

что если вызывать вот так
Perl
1
2
3
4
5
$query = "execute zhoppa s ruchkoj";
print "eee call result = ", eee($uery);
 
$query = "execute zhoppa s ruchkoj";
print "fff call result = ", fff($query);
то тоже будет всё нормально.
1
166 / 164 / 27
Регистрация: 20.04.2010
Сообщений: 607
18.03.2014, 09:47  [ТС] 3
Цитата Сообщение от volodin661 Посмотреть сообщение
модификатор /g
Копипаст =) Не думал что он так сказывается.
Цитата Сообщение от volodin661 Посмотреть сообщение
выражение $_[n] - это простой alias на собственно переданный аргумент
Да. Это я понял. Но применение регулярки к строке разве меняет ее?
Цитата Сообщение от volodin661 Посмотреть сообщение
оптимизатор применил шаблон согласно модификатору /g
к одному и тому же выражению 2раза
Но контекст то функций разный. По правилам хорошего тона( по крайней мере С-шного) он должен был применить его еще раз, независимо от предыдущих вызовов.


Просто на С, сие работало бы без проблем)
Спасибо за развернутый ответ.
0
5989 / 1998 / 323
Регистрация: 10.12.2013
Сообщений: 6,882
18.03.2014, 11:25 4
Вот так нагляднее:

Perl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/usr/bin/perl -w
use strict;
 
sub first {
    return ( $_[0] =~ m/(\w+)/ig ) 
        ? "first-ok($1)\n"
        : "first-no\n";
}
 
 
sub another {
    return ( $_[0]=~ m/(\w+)/ig )
        ? "another-ok($1)\n"
        : "another-no\n";
}
 
sub yet_another {
    return ( $_[0]=~ m/(\w+)/ig )
        ? "yet_another-ok($1)\n"
        : "yet_another-no\n";
}
 
my $query = "aaaa bbbb cccc dddd";
print "first call result = ", first($query);
 
print "another call result = ", another($query);
 
print "yet_another call result = ", yet_another($query);
Результат:
Кликните здесь для просмотра всего текста
first call result = first-ok(aaaa)
another call result = another-ok(bbbb)
yet_another call result = yet_another-ok(cccc)
1
18.03.2014, 11:25
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.03.2014, 11:25
Помогаю со студенческими работами здесь

Объяснить работу функции, возвращающей указатель на указатель на char
Добрый день! Сможете объяснить что означает запись char **InputFile(int &strings);? Почему...

Объяснить работу
Что здесь значит if(i>5... И что делает конкретно i и что означает #define...

Объяснить работу кода
#include <iostream> using namespace std; int main() { int i, j; for (i=2; i<6; i++) { for...

Объяснить работу кода
Подскажите пожалуйста как работает этот код при F(9). На экран выводит 131159, но как это...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru