Что означает синтаксис << 'm' = ~ m >> в perl?

Итак, я понимаю, что perl имеет очень необычный синтаксис, но наткнулся на фрагмент кода на работе, который на другой день оставил меня в замешательстве. Может ли кто-нибудь объяснить мне, что это значит:

<<'m'=~m>>
print $a unless $b;
return;
m
;

Он похож на синтаксис HEREDOC, но не в той форме, которую я когда-либо видел.

Ответ 1

Этот секретный синтаксис известен как богато украшенный меч с двумя лопастями и обычно обозначается как:

<<m=~m>>

Comments here

m
;

Это взломать многострочные комментарии, используя синтаксис heceptoc и оператор сопоставления (=~) с > как разделитель.

Примечание, в качестве косой черты / не используются в качестве разделителя для соответствия, требуется оператор "m". Например, $my_var =~ /test/ эквивалентно $my_var =~ m>test>, тогда как $my_var =~ >test> будет недействительным.

Обратите внимание на то, что первый символ m в вашем фрагменте заключен в одинарные кавычки, то есть переменные $a и $b не будут интерполированы. Если бы эти кавычки были опущены (согласно моему приведенному примеру кода), perl автоматически добавит двойные кавычки к маркеру конца, и любые последующие переменные будут интерполированы. Это вызовет проблемы, если $a и $b больше не определены, и вы используете use warnings;.

Чтобы сделать богатый пример с двумя лезвиями выше более понятным (но все же не рекомендуется), мы могли бы написать:

<<"END" =~ //

Comments here

END
;

Обратите внимание, что =~ // является избыточным, поэтому это эквивалентно:

<<"END";

Comments here

END

Это просто стандартный синтаксис heredoc в контексте void.

Я бы не рекомендовал использовать это в производственном коде, поскольку наличие строки в контексте void может вызвать проблемы. Плюс этот код является головным scratcher для даже самых опытных программистов perl и бессмысленно трудно читать и поддерживать! Если вы хотите создать правильные многострочные комментарии, я бы предложил придерживаться pod, как описано здесь Как ввести многострочный комментарий в Perl?

Надеюсь, что это очистит.

Ответ 2

Запуск B:: Deparse помогает многое понять, как perl обрабатывает этот фрагмент кода (при условии, что он находится в файле test.pl):

perl -MO=Deparse  test.pl 

показать нам:

"print \$a unless \$b;\nreturn;\n" =~ //;
test.pl syntax OK

Итак, как вы можете видеть, perl пытается сопоставить пустой regexpr с этой строкой: "print \$a unless \$b;\nreturn;\n"