Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re: Code Loop?

by hippo (Bishop)
on Aug 08, 2018 at 13:30 UTC ( [id://1220099]=note: print w/replies, xml ) Need Help??


in reply to Code Loop?

The code can be shortened to simply:

use 5.010; say $#@x[1];

Since this compiles even with strict you know that you've done something odd. Corion's explanation is spot on.

Replies are listed 'Best First'.
Re^2: Code Loop?
by LanX (Saint) on Aug 08, 2018 at 13:42 UTC
    It would be nice to have a strict feature to catch such special variable "zombies", but I'm not sure how to implement it.

    Point is that $@ is a special global package variable, with the glob *main::@ , hence this glob has slots for an array, hash, function,... without being declared.

    like

    D:\Users\lanx>perl -E "use strict; say @@" D:\Users\lanx>perl -E "use strict; say *@" *main::@

    IMHO in at least 95% of the cases these slots are used accidentally.

    Some use them intentionally, but could activate a pragma in these cases. °

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

    °) dunno many obfuscators who use strict anyway ;-)

      You could poison them with a tie to catch uses at runtime:

      package Tie::Poison; sub TIESCALAR { ... } sub TIEARRAY { ... } sub FETCH { my $var = tied $_[0]; die "Prohibited variable '$$var' used"; } package unusual_variable_names; our @unusual = qw( @@ @$ ... ); sub unimport { for my $name (@unusual) { no strict 'refs'; tie @{ $name }, 'Tie::Poison', $name; }; }; ... package main; no unusual_variable_names;
        yep but as you said it's only runtime.

        But it should be feasible to write a an op-code walker catching them at compile time in the UNITCHECK phase.

        D:\>perl -MO=Terse -E "use strict; say @@" LISTOP (0x2820630) leave [1] OP (0x2820600) enter COP (0x2820670) nextstate LISTOP (0x2820700) say OP (0x28206d0) pushmark UNOP (0x2820740) rv2av [2] <-- array PADOP (0x2820778) gv GV (0x1dede0) *@ <-- of glob *@ -e syntax OK D:\>perl -MO=Concise -E "use strict; say @@" 7 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 48 -e:1) v:%,*,&,{,x*,x&,x$,$,469764096 ->3 6 <@> say vK ->7 3 <0> pushmark s ->4 5 <1> rv2av[t2] lK/3 ->6 <-- array 4 <#> gv[*@] s ->5 <-- of glob *@ -e syntax OK

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Re^2: Code Loop?
by bitman (Scribe) on Aug 08, 2018 at 13:38 UTC
    Ahhh, so it's $#@ (as Corion says) times the (random) address of an anonymous array containing the 1?
      > times the (random) address of an anonymous array containing the 1?

      yes since x is imposing numeric context on it's RHS

      D:\>perl -E "say [1]; say 0+[1]" ARRAY(0x24e6d8) 2418704

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1220099]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (3)
As of 2024-04-19 20:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found