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

The code below produces the error: Can't use string ("1000") as a symbol ref while "strict refs" in use at junk.pl line 8. under 5.10 and 5.22.

I know how to work around it; but for the life of me I cannot see why I need to?

#! perl -slw use strict; my $i = 3; my $n = 1000; loop: print $n +4; #- 12; print $n +8; #- 8; print $n +12; #- 4; print $n +16; #- 0; $n += 16; goto loop if --$i;

With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
In the absence of evidence, opinion is indistinguishable from prejudice. Not understood.

Replies are listed 'Best First'.
Re: Why does this code think I'm trying to use symbolic references?
by choroba (Cardinal) on Jun 12, 2016 at 20:58 UTC
    Indirect object notation for print strikes back:
    $ perl -MO=Deparse,-p 1.pl BEGIN { $^W = 1; } BEGIN { $/ = "\n"; $\ = "\n"; } use strict; (my $i = 3); (my $n = 1000); loop: print($n 4); print($n 8); print($n 12); print($n 16); ($n += 16); ((--$i) and (goto loop)); 1.pl syntax OK

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      Thanks!


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
      In the absence of evidence, opinion is indistinguishable from prejudice. Not understood.
Re: Why does this code think I'm trying to use symbolic references?
by GrandFather (Saint) on Jun 12, 2016 at 21:10 UTC

    print $n ... expects $n to contain a file handle. 1000 is not a file handle and "strict refs" forbids using the string to reference a variable. Consider:

    #! perl my $n = 'STDOUT'; print $n "Now we's happy\n"; use strict; print $n "Now we's not\n";

    Prints:

    Now we's happy Can't use string ("STDOUT") as a symbol ref while "strict refs" in use + at ...\noname.pl line 8.
    Premature optimization is the root of all job security
      print $n ... expects $n to contain a file handle.

      But print $n + 4; doesn't; and that was my intent. And in (almost, if not) all other circumstances $n +4 and $n + 4 are equivalent, so It just didn't click even after I found that adding another space fixed the problem.

      As I'm normally quite prodigious with my horizontal whitespace, it's just not something I've encountered before.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
      In the absence of evidence, opinion is indistinguishable from prejudice. Not understood.
        ... I'm normally quite prodigious with my horizontal whitespace ...

        Either prodigality or parsimony seem to work; e.g.,  print $n+4; also avoids the problem. Apparently it's only  $n +4 that Perl looks at and says "Oh, of course: a unary plus!" (I haven't tested it, but I assume the same would happen | I've tested it, and the same thing happens with a pseudo-unary minus.)

        Update: Per perlop, unary + and - have higher precedence than the binary operators.


        Give a man a fish:  <%-{-{-{-<

Re: Why does this code think I'm trying to use symbolic references?
by shmem (Chancellor) on Jun 13, 2016 at 12:22 UTC
    I know how to work around it; but for the life of me I cannot see why I need to?

    This is hairy. It is one case where whitespace matters in perl.

    Two things are going on here:

    1. resolution of the args to print as indirect object notation vs. resolvable term
    2. determination of the meaning of '+' in '$n +4'

    use strict; $n = 1000; $\=$/; print $n +4; # indirect object notation, + is sign marking 4 as posit +ive (unary plus) print $n + 4; # $n + 4 is addition, result is printed print +$n +4; # unary + prevents $n from being interpreted as file han +dle, 1004 is printed print ($n +4); # same as case 1 print ($n + 4); # same as case 2 print+($n +4); #same as case 3
    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
      This is hairy.

      Indeed. I'm just amazed that I have never encountered this before. I regularly hit this one:

      $x = 10; print ( $x + 1 ) / 3;; 11

      But never to my recollection the OP problem.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
      In the absence of evidence, opinion is indistinguishable from prejudice. Not understood.

      I understand it is strange to hit whitespace issues in Perl (where weirdness like my$   n = 1 is legal) but this seems sensible and, this part, not hairy; I'd be alarmed if it worked any differently. Only the print(list) and file handle stuff is surprising and Perl users learn those issues, I hope, pretty early. +4 looks, like -4, unambiguously signed. Maybe the negative reads more clearly since we're used to never seeing the positive.

      print $n -4;
        I understand it is strange to hit whitespace issues in Perl (where weirdness like my$   n = 1 is legal) but this seems sensible and, this part, not hairy; I'd be alarmed if it worked any differently.

        Yes, yes and yes; and yes. My statement is ambiguous, too: not the implemented behaviour (which is fine) is hairy, instead I qualify the edge case itself as such. And it shows - again - how well kept and thought out/through perl is. p5p are doing an awesome job.

        perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'