2013-07-23 3 views
2

Perl пропускает мой DWIM (тройной ?:) и заставляет регулярное выражение.Почему perl parses regex

perl -e "print $bool ?'T' :'F'" 
Use of ?PATTERN? without explicit operator is deprecated at -e line 1. 
Search pattern not terminated or ternary operator parsed as search pattern at -e 
line 1. 

Почему это так? Эти два примера правильно разобран тройной оператор,

perl -e "print $bool ? 'T' :'F'" 
perl -e "print [] ?'T' :'F'" 

Это на окнах, но почти то же самое на * NIX

perl -e 'print $bool ?"T" :"F"' 

так это не выглядит как оболочки связаны между собой.

+0

Похоже, что одно из этих раздумий в Perl, возникающее из обратной совместимости. Ввод «использования шаблона без явного оператора» в Google дает много результатов, все одинаково не связанные с сопоставлением шаблонов. И тот факт, что одно пространство делает разницу между ошибкой и ошибкой, просто yuk! – sundar

ответ

7

?...? является оператором, как видно из here, и проблема здесь является неоднозначной. Компилятор не знает, видит ли он шаблон или тройной оператор (как следует из последующего предупреждения), поэтому он догадывается и

Я думаю, что это как-то связано с print(), устанавливающим его для fal л, в том, что print() имеет следующий синтаксис:

print FILEHANDLE LIST 

Таким образом, предварительно определяет $bool как дескриптор файла, и ?'.... как заявление. Затем он замечает, что $bool не является дескриптором файла, но троянец уже задействован в своей ошибочной роли. Вы увидите, что следующие работы:

perl -e"print STDOUT $bool ?'t' :'f'" 
+0

Интересно видеть, что parens вообще не помогают на' perl -e 'print ($ bool?' T ': 'F') "' все еще дает ошибку –

+0

'print (FILEHANDLE LIST)' и 'print (LIST)' отлично, поэтому неопределенность остается. – ikegami

+0

@mpapec В действительности нет никакой разницы, так как это не вопрос приоритетов или параметров функции. Это связано с [опознаванием косвенных объектов] (http://perldoc.perl.org/perlobj.html#Indirect-Object-Syntax). – TLP

3

Вы в Windows или на * nix?

В Linux я не получаю никаких предупреждений, когда я включаю "и" (perl -e 'print $bool ? "T" :"F"'). То, как вы написали $bool интерполируется оболочкой, пустой строкой, и код становится perl -e "print ?'T' :'F'", правильно запускает предупреждение.

+0

почти такая же история с 'perl -e 'print $ bool?" T ":" F "'' под linux, поэтому она не связана с оболочкой –

+0

странная. Тем более, что Deparse считает, что 2 версии (с пробелом и без пробела между вопросительным знаком и цитатой) одинаковы, попробуйте 'perl -MO = Concise -e'print $ bool? «F»: «T» ''vs' perl -MO = Concise -e'print $ bool? "F": "T"' ' – mirod

+0

к сожалению' Concise' ничего не показывает, когда нет места после '? 'mark –

6

Синтаксис Perl имеет двусмысленности.

print $bool ?... 

может быть разобрано как

print FILEHANDLE LIST 

    +----------------- print 
    |  +----------- FILEHANDLE 
    |  | +------ LIST (A regex match ?...?) 
    |  | |  
_____ _____ ____ 
print $bool ?... 

или

print LIST 

    +----------------- print 
    |  +--------- LIST (A conditional operator ...?...:...) 
    |  |   
_____ __________ 
print $bool ?... 

Не глядя слишком далеко вперед, perl неправильно угадывает, что вы имели в виду первый, но позволяет вам знать, что он догадался ,

Search pattern not terminated or ternary operator parsed as search pattern 

Обходные:

  • Добавление пробела после ? (print $bool ? 'T' :'F';) делает его не угадать (так как она уже не выглядит так же, как ?...?).

  • Добавление + до того, как дескриптор файла (print +$bool ?'T' :'F';) заставляет его правильно угадывать (поскольку это уже не действительное выражение дескриптора файла).

  • Удалите пространство перед ? (print $bool?'T' :'F';), что делает его правильным (поскольку оно больше не является допустимым выражением дескриптора файла).

  • Добавление дескриптора файла (print STDOUT $bool ?'T' :'F';) делает его правильным (начиная с $bool должно быть начало списка аргументов).

+0

(Да, это в основном перефразировка, но в то время не было принято ответа, и я попытался сделать объяснение кристально чистым.) – ikegami

+0

+1 Его хорошее объяснение. – TLP