Самый простой способ исправить ваш код - это добавить круглые скобки вокруг my
и удалить ??{
. Вот фиксированная программа:
#!/usr/bin/perl
use strict;
my $var = 1234567890;
foreach (1 .. 9){
theSub($_);
}
sub theSub {
my($int) = @_;
my($var2) = $var =~ m/($int)/;
print "$var2\n";
}
Одной из проблемных строк в вашем коде была my $int = @_
, которая была эквивалентна my $int = 1
, потому что она оценивала @_
в скалярном контексте, давая количество элементов в @_
. Чтобы получить первый аргумент вашего подпрограммы, используйте my($int) = @_;
, который оценивает @_
в контексте списка, или выберите первый элемент, используя my $int = $_[0];
, или выберите + удалить первый элемент, используя my $int = shift;
Была похожая проблема в строке my $var2 =
, вам также нужны скобки для оценки соответствия регулярному выражению в контексте списка, получая список ($1, $2, ...)
и присваивая $var2 = $1
.
Конструкция (??{...})
, которую вы пытались использовать, имела эффект, противоположный тому, что вы хотели: (среди прочего) она компилировала ваше регулярное выражение в первый раз, когда оно использовалось для сопоставления. Для регулярных выражений, содержащих $
или @
, но не содержащих ??{...}
, Perl перекомпилирует регулярное выражение автоматически для каждого совпадения, , если не указан флаг o
(например, m/$int/o
).
Конструкция (??{...})
означает: используйте код Perl ...
для генерации регулярного выражения и вставьте здесь это регулярное выражение. Для получения дополнительной информации выполните поиск ??{
на http://perldoc.perl.org/perlre.html. Причина, по которой это не сработало в вашем примере, заключается в том, что вам потребовался бы дополнительный слой скобок для захвата $1
, но даже с my ($var2) = $var =~ m/((??{$int}))/
это не сработало бы, потому что ??{
имеет недокументированное свойство: он вызывает компиляцию своего аргумента в первый раз, когда регулярное выражение используется для сопоставления, поэтому my ($var2) = $var =~ m/((??{$int + 5}))/
всегда соответствует 6
.