in reply to Gods, don't try to justify using symrefs!
in thread encapsulation via compiler-checked symrefs

Actually, '__PACKAGE__' and '__LINE__' [...] are special compiler directives. [...] They're NOT variables, hence they don't fall under strict's purview, nor any other purview, for that matter.

__PACKAGE__ doesn't bypass strict because it is some "special" "non-variable". It gets past strict because it is a compile-time constant (as I discussed in the thread that introduced this topic, self-referent hash for your packages).

Some more examples:

#!/usr/bin/perl -w my @strictures; BEGIN { require strict; if( ! grep /-v/, @ARGV ) { @strictures= "refs"; } } use strict @strictures; sub name1() { return "Foo::Bar" } sub name2 { return "Foo::Bar" } "Foo::Bar"->{key}= "value"; # No error print name1->{key},$/; # No error, prints "value" eval { print name2->{key},$/ # Fatal run-time error # Can't use string ("Foo::Bar") as a HASH ref while "strict refs" } or warn $@; { package Foo::Bar; print __PACKAGE__->{key},$/; # No error, prints "value" } eval q{ sub name3() { return "Foo" } sub name4 { return "Foo" } "Foo"->{key}= "bar"; # If only strict 'refs', then prints "bar" w/ no errors # (-v)Global symbol "%Foo" requires explicit package name print name3->{key},$/; # If only strict 'refs', then prints "bar" w/ no errors # (-v)Global symbol "%Foo" requires explicit package name eval { print name4->{key},$/; # Can't use string ("Foo") as a HASH ref while "strict refs" } or warn "Line ",__LINE__,": $@"; eval q{ package Foo; print __PACKAGE__->{key},$/; # Use of uninitialized value in print 1; } or warn "Line ",__LINE__,": $@"; } or warn "Line ",__LINE__,": $@";
Which boils down to some interesting things:

Which makes me swing more toward the opinion that compile-time constant strings getting past use strict "refs" is simply a bug (and should put one more nail in the coffin of this hack).

Update: BTW, the reason that compile-time string constants get past use strict "refs", is (as I suspected) because the resulting code gets compiled as if the string were entered "bare":

perl -MO=Deparse -e "'Foo'->{key}= 'value'" $Foo{'key'} = 'value'; -e syntax OK

        - tye (but my friends call me "Tye")