Вызов «скаляр» для результатов оператора диапазона (..) в Perl - PullRequest
3 голосов
/ 30 июля 2010

Итак, я считаю, что это как-то связано с разницей между массивами и списками, но я не не понимаю что здесь происходит.Может кто-нибудь объяснить, как и почему Perl трактует выражение как (1..4) иначе, чем (1, 2, 3, 4) и @{[1..4]}?

$ perl -de1

Loading DB routines from perl5db.pl version 1.31
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(-e:1): 1
  DB<1> x scalar (1,2,3,4)
0  4
  DB<2> x scalar (1..2,3,4)
0  4
  DB<3> x scalar (1,2..3,4)
0  4
  DB<4> x scalar (1,2,3..4)
0  ''
  DB<5> sub foo { (1..4) } # (the actual problem case, except 4 would be a variable)
  DB<6> x scalar foo()
0  ''
  DB<7> sub bar { @{[1..4]} } # (the workaround)
  DB<8> x scalar bar()
0  4

1 Ответ

11 голосов
/ 30 июля 2010

«Оператор диапазона», который создает список просто , не существует в скалярном контексте - вместо этого оператор .. при использовании в скалярном контексте является «оператором триггера».Оператор триггера начинает возвращать false, продолжает возвращать false до тех пор, пока его левый аргумент не станет true, затем продолжает возвращать true, пока его правый аргумент не станет true, после чего он возвращает false и возвращается в исходное состояние.Если все это звучит довольно бесполезно, рассмотрим

while (<>) {
  print if /BEGIN/ .. /END/;
}

. Оператор .. начинается с false, поэтому строки из файла не печатаются.Но как только регулярное выражение /BEGIN/ совпадает, триггер становится истинным, и все следующие строки будут напечатаны, пока регулярное выражение /END/ не совпадет.В строке, следующей за «END», триггер снова будет ложным.Таким образом, эффект состоит в том, чтобы печатать только строки между (и включая, но вы можете контролировать это) «НАЧАЛО» и «КОНЕЦ».

В $. есть немного больше магии, если любая из сторон постоянна, ноне очень важно.Подробнее об операторе триггера читайте в perldoc perlop .

...