Опубликован: 18.06.2007 | Доступ: свободный | Студентов: 1420 / 43 | Оценка: 4.14 / 3.29 | Длительность: 12:44:00
ISBN: 978-5-94774-604-4
Лекция 9:

Встроенный код, переменные local и my

И еще аналогичный и очень интересный пример:

my $a='1';
$_='2';
print "\$&=$&\n" if $a =~ /^1(?{$_='z'; print "\$_=$_ \$a=$a\n"})$/;
print "\$_=$_ \$a=$a";

Будет напечатано

$_=z $a=z
$&=z
$_=2 $a=z

Из результата мы видим следующее:

  • поиск завершился успешно;
  • переменная $& должна бы содержать 2, а содержит z ;
  • во встроенном коде мы присвоили переменной $_ z, и $a тут же получила это же значение;
  • вне оператора поиска переменная $_ сохраняет свое старое значение 2, а $a хранит полученное во встроенном коде значение z.

Можно сделать вывод, что внутри регулярного выражения переменная $_ является синонимом переменной, содержащей целевой текст, как и в операторах map и for (), и переменная $_ локализуется внутри регулярного выражения. Поэтому изменять $_ внутри регулярного выражения так же опасно, как и переменную с целевым текстом.

И еще относительно встроенного кода: встроенный код, который содержится внутри интерполируемых переменных, тоже выполняется, но для этого нужна директива

use re 'eval';

При выполнении скрипта

$_='aaa';
my $a='(?{print "OK "})';
print "$&" if /^aaa$a$/;

Возникнет ошибка

Eval-group not allowed at runtime, use re 'eval' in regex m/^aaa(?{print "OK"})$/ at a.pl line 7.

С директивой use re 'eval' все в порядке:

use re 'eval';

$_='aaa';
my $a='(?{print "OK "})';
print "$&" if /^aaa$a$/;

Вывод: OK aaa.

Заметим, что эта директива не действует внутри встроенного кода:

my $a='(?{use re "eval"; print "OK "})';
print "$&" if /^aaa$a$/;

потому что проверка на встроенный код происходит раньше его использования. Это защищает от использования чужого встроенного кода, например, кода из ввода пользователя.

Гулзира Урбисинова
Гулзира Урбисинова
Сергей Крупко
Сергей Крупко

Добрый день.

Я сейчас прохожу курс  повышения квалификации  - "Профессиональное веб-программирование". Мне нужно получить диплом по этому курсу. Я так полагаю нужно его оплатить чтобы получить диплом о повышении квалификации. Как мне оплатить этот курс?