Как написать простую подпрограмму в Perl, которая принимает строку и возвращает строку? - PullRequest
0 голосов
/ 22 декабря 2010
sub getHeading
{
    my $var = $_[0];
    my $match;
     if ($match = ($var =~ m/$fivetonine/))
     {
        return "=";
     }
     if ($match = ($var =~ m/$tentofourteen/))
     {
        return "==";
     }
     if ($match = ($var =~ m/$fifteentonineteen/)){
        return "===";
     }
     return "===";
}
my $ref_to_getHeading = \getHeading;

и я вызываю его через:

$html =~ s/(.*)<font size="([^"]+)">(.+)<\/font>(.*)/$ref_to_getHeading($2)$1$3$4$ref_to_getHeading($2)/m;

Я хочу передать строку в эту функцию, я хочу проверить, является ли она одним из 3 разных совпадений, и вернуть соответствующеечисло знаков =, я делаю это неправильно, но я не могу понять, как заставить его принимать параметры?Я получаю ошибку во время выполнения, говоря, что $ var инициализирован?Я пытался использовать @_, но я не совсем понимаю, в чем разница.

Любая помощь очень ценится, я никогда раньше не писал Perl, и это моя первая настоящая программа.

Ответы [ 2 ]

3 голосов
/ 22 декабря 2010

Двойная ошибка там.

Во-первых, вы не берете ссылку на функцию - вам нужно добавить амперсанд.

Но даже если вы сделаете это, она не будетРабота.В вашей замене отсутствует флаг / e: вы не можете разыменовать кодовую ссылку в строке, как вы обычно делаете с (scalar | hash | array) ref:

my $example = sub { return "hello" };
say "$example->()"; #Will stringify the coderef.

Вам либо нужен/ e flag,

$html =~ s/etc/$ref_to_getHeading->($2) . "$1$3$4" . $ref_to_getHeading->($2)/em;

Или небольшая хитрость:

$html =~ s/etc/@{[$ref_to_getHeading->($2)]}$1$3$4@{[$ref_to_getHeading->($2)]}/m;

РЕДАКТИРОВАТЬ: Черт возьми, я медленный машинистка ... Во всяком случае, в любом случае, вы должны быть в состоянии позвонитьподпрограмма напрямую, поэтому нет необходимости в coderef.

3 голосов
/ 22 декабря 2010

Линия my $ref_to_getHeading = \getHeading; не делает то, что вы думаете, она делает. Чтобы взять ссылку на подпрограмму:

my $ref_to_getHeading = \&getHeading;  # note the &

Итак, вы на самом деле звонили getHeading и сохраняли результат. Поскольку вы не передали аргументы, вы получили предупреждение о неопределенном значении.

Однако подстановка никогда не вызовет coderef, для этого вам нужно добавить модификатор e, чтобы выполнить текст замены через eval:

$html =~ s/.../join '' => getHeading($2), $1, $3, $4, getHeading($2)/me;

Вы можете столкнуться с проблемами здесь, когда getHeading сбрасывает параметры совпадения слишком рано. В таком случае попробуйте написать это так:

$html =~ s{...}{
    my $body = $1 . $3 . $4;
    my $heading = getHeading($2);
    $heading . $body . $heading
}me;

Смена скобок для s/// не требовалась, просто мне проще читать многострочный фигурный блок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...