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:
- Compile-time string contants that contain "::"
can be used as symbolic references even under use strict "refs".
- Compile-time string contants that don't contain "::"
generate a fatal "Global symbol requires explicit package"
error under use strict "vars".
- The (horrid) __PACKAGE__-> trick,
when used in a package whose name contains no "::", fails
under use strict "vars" and tries to access a hash
whose name is __PACKAGE__."::".__PACKAGE__ (instead of the
usual name of __PACKAGE__).
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") |