mpapec
mpapec

Reputation: 50647

Why perl parses regex

Perl misses my DWIM (ternary ?:) and forces 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.

Why is that so? Following two examples have correctly parsed ternary operator,

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

This is on windows, but almost same thing on *nix

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

so it doesn't look like shell related.

Upvotes: 2

Views: 972

Answers (3)

ikegami
ikegami

Reputation: 385839

Perl syntax has ambiguities.

print $bool ?...

can be parsed as

print FILEHANDLE LIST

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

or as

print LIST

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

Without looking too far ahead, perl incorrectly guesses that you meant the first one, but lets you know that it guessed.

Search pattern not terminated or ternary operator parsed as search pattern

Workarounds:

  • Adding a space after the ? (print $bool ? 'T' :'F';) makes it guess correctly (since it no longer looks as much like ?...?).

  • Adding a + before the file handle (print +$bool ?'T' :'F';) makes it guess correctly (since it's no longer a valid file handle expression).

  • Remove the space before the ? (print $bool?'T' :'F';) makes it guess correctly (since it's no longer a valid file handle expression).

  • Adding a file handle (print STDOUT $bool ?'T' :'F';) makes it guess correctly (since $bool must now be the start of the argument list).

Upvotes: 6

TLP
TLP

Reputation: 67910

The ?...? is an operator, as seen here, and the problem here is one of ambiguity. The compiler does not know if it is seeing a pattern or a ternary operator (as the subsequent warning says), so it guesses, and guesses wrong.

I think it has something to do with print() setting it up for a fall, in that print() has the syntax:

print FILEHANDLE LIST

So, it pre-determines $bool as a file handle, and ?'.... as a statement. Then it notices that $bool is not a file handle, but the ternary is already cast in its faulty role. You will notice that the following works as intended:

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

Upvotes: 7

mirod
mirod

Reputation: 16161

Are you on Windows or on *nix?

On linux I get no warnings when I switch " and ' ( perl -e 'print $bool ? "T" :"F"'). The way you wrote it the $bool is interpolated by the shell, to an empty string, and your code becomes perl -e "print ?'T' :'F'" which correctly triggers the warning.

Upvotes: 3

Related Questions