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

Just discovered my script compiles OK with "$ _". Don't remember it mentioned in the manuals. Can't it lead to all sorts of funny things:

C:>perl -E "$ x = 1; say $ x; say qq($ x)" 1 1 C:>perl -E "$x = 1; $ x= 5; say qq($ x)" 5 C:>perl -E "$name = q(Fred); $debt = 50; say qq(You pay me ${debt}$ 00 + cents, $name, or else!)" You pay me 50 cents, Fred, or else!

Replies are listed 'Best First'.
Re: What for sigils were allowed to be separated from identifiers?
by Eily (Monsignor) on Nov 29, 2017 at 13:55 UTC

    This is not the case in regex though, $str =~ qq/$ x/; will use the value of $x as a regular expression, while $str =~ qr/$ x/; just doesn't match anything ($ is the position before \n, so the characther after that can neither be a space nor x). This means whitespace is not ignored when doing so yields a non-sensical expression :P

    perl -E "$x = 'Hello'; say $ x =~ qr/$ x/ ? 'Match': 'No match'" No match perl -E "$x = 'Hello'; say $ x =~ qq/$ x/ ? 'Match': 'No match'" Match

    Edit: it's whitespace, not blankspace, got the wrong word :)

Re: What for sigils were allowed to be separated from identifiers?
by 1nickt (Canon) on Nov 29, 2017 at 13:47 UTC

    Good example of why you should always use warnings;?

    $ perl -wE '$name = q(Fred); $debt = 50; say qq(You pay me ${debt}$ 00 + cents, $name, or else!)' Use of uninitialized value $00 in concatenation (.) or string at -e li +ne 1. You pay me 50 cents, Fred, or else!

    Update: Also a good demo of why interpolation can be dangerous and the case for using sprintf?

    $ perl -E '$name = q(Fred); $debt = 50; say sprintf q(You pay me %s$ 0 +0 cents, %s, or else!), $debt, $name' You pay me 50$ 00 cents, Fred, or else!


    The way forward always starts with a minimal test.
Re: What for sigils were allowed to be separated from identifiers?
by Discipulus (Canon) on Nov 29, 2017 at 16:28 UTC
    perl parser is not interested in spaces until the code it's clear, at least from perl point of view.

    This is a good thing for you, infact you can print a boublequoted string as multiline expression.

    If you by other hand insert (even if allowed) white spaces between sigils and identifiers, you are somehow shooting on your own feet.

    Anyway perlintro states:

    > Whitespace is irrelevant:

    print "Hello, world" ;

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

      Whitespace is irrelevant
      p r i n t "Hello, world"; doesn't print "Hello, world" though, so you can't just put whitespace anywhere.
      Also $x = "Hello"; print "$ x" will print "Hello" but @x = "Hello"; print "@ x" will print "@ x", and @$ x, $# x and $ #x are all syntax errors unless you remove the spaces.
      #Edited: added those examples use feature 'say'; our $x = "Hello"; our @y = "Hi"; our $z = ["Bonjour"]; while (<DATA>) { chomp; print "$_ \t"; no warnings; eval "$_; 1" or say $@ =~ tr/\n/ /r; } __DATA__ say "$x"; say "$ x"; say "@y"; say "@ y"; say @ y; say $#y; say $# y; say $ #y; say @ $z; say @$ z;
      say "$x"; Hello say "$ x"; Hello say "@y"; Hi say "@ y"; @ y say @ y; Hi say $#y; 0 say $# y; syntax error at (eval 6) line 2, at EOF (Might be a +runaway multi-line ;; string starting on line 1) say $ #y; syntax error at (eval 7) line 1, at EOF say @ $z; Bonjour say @$ z; syntax error at (eval 9) line 1, near "@$ z"

      If you [...] insert [...] white spaces between sigils and identifiers, you are somehow shooting on your own feet.
      If you do it on purpose yes, but it's pretty easy to do it by mistake, either because of a typo, or because you expected spaces to be relevant inside a string, or even in some cases without noticing what's wrong, and perl may not warn you:
      use v5.14; use strict; use warnings; use constant MASK => 0xF0; use constant VAL => 0x0F; sub get_val1 { VAL } sub get_val2() { VAL } sub get_mask { MASK } # Is & a function sigil or the bitwise and? say VAL & get_mask; say get_val1 & get_mask; say get_val1 & MASK; say get_val2 & MASK; say get_val1() & MASK;
      0 15 15 0 0

      > Whitespace is irrelevant

      Yes indeed, and don't I over-abuse this fact with non-standard indentation, building geometric figures from my source, to help me better read and remember what it was, in 1-2 years. But I never saw sigils standing separate, even in code meant for puzzling and obfuscation, e.g. this, have you?

Re: What for sigils were allowed to be separated from identifiers?
by Anonymous Monk on Nov 29, 2017 at 17:46 UTC
    The BNF syntax for Perl is very loose. You will from time to time find things (especially in use declarations) that ought to produce syntax errors, but don't.

      chromatic said

      First of all, there's no "BNF grammar" in the interpreter. There's a parser and a lexer which you could, if you were enterprising enough, potentially represent in Backus-Naur Form, but it's not expressed as such anywhere within the Perl source code, and there is no singular representation of grammar within the Perl source.

      I don't know much about the subject, but I'd be willing to believe that chromatic does.

      You say "especially in use declarations", are you actually making a reference to the thread this answer came from?