rovf has asked for the wisdom of the Perl Monks concerning the following question:

use strict; use warnings; sub func {} func ? '-N ' : '';
yields Search pattern not terminated or ternary operator parsed as search pattern. The error goes away if I call the function as func(). My question: Why does a question mark after a bareword parse as search pattern? Is it just to comply with those internal functions such as grep or split, which accept a regexp as first argument, or is there a deeper reason for this seemingly oddity?

-- 
Ronald Fischer <ynnor@mm.st>

Replies are listed 'Best First'.
Re: Why do I need parentheses here?
by ikegami (Patriarch) on May 27, 2009 at 13:19 UTC

    "?" can start both a term (?PATTERN?) and an operator (the conditional operator). Perl has no way of knowing which one you intended here. Since it followed a sub call, Perl assumed you were specifying arguments, so it treated the "?" as the start of a term. Same goes for "/", unary-"-" and unary-"+".

    Solutions:

    func() ? '-N ' : ''
    (func) ? '-N ' : ''
    sub func() {} func ? '-N ' : ''

    Is it just to comply with those internal functions such as grep or split, which accept a regexp as first argument, or is there a deeper reason for this seemingly oddity?

    No. func ?PATTERN?; is no different than func $x+1; (and even more similar to func -3;). There's nothing special (or odd) about it.

      func ?PATTERN?; is no different than func $x+1;. There's nothing special (or odd) about it.

      I think I got it. So func ?PAT? is just another way of writing

      func($_ =~ ?PAT?)

      -- 
      Ronald Fischer <ynnor@mm.st>
        Yes. ?PAT? and $_ =~ ?PAT? are equivalent, just like /PAT/ and $_ =~ /PAT/ are. (Aforementioned split is exceptional since it treats /PAT/ as qr/PAT/ or similar.)
        Checking ;)
        C:\>perl -MO=Deparse,-p -e"sub foo{} foo ?bar? sub foo { } foo(?bar?); -e syntax OK
        Yes
Re: Why do I need parentheses here?
by jettero (Monsignor) on May 27, 2009 at 13:14 UTC
    If you give func a prototype, you probably don't: sub func() {} # and it'll probably work.

    -Paul