TLDR: See question title.
In the original version of a question, there was use strict ();
at the top of the program. No variables were declared with my
. The program worked. I pointed that out that the code wouldn't work because of the missing my
s, but it turns out I was mistaken.
$ perl e 'use strict (); $foo = 1'
This program works. It doesn't crash. But obviously this crashes:
$ perl -e 'use strict; $foo = 1'
Global symbol "$foo" requires explicit package name (did you forget to declare "my $foo"?) at -e line 1.
Execution of -e aborted due to compilation errors.
My first idea was to deparse it to see if something else is going on.
$ perl -MO=Deparse -e 'use strict (); $foo = 1'
use strict ();
$foo = 1;
-e syntax OK
But it's not. Then it got me thinking, you can do use strict 'vars'
, which only turns on the vars thing1. It obviously does that by calling import
.
The use strict
is the same as BEGIN { require strict; strict->import; }
, so the same rule that goes for modules should apply for pragmata too. If I do use Foo ()
, nothing is imported. Hence, use strict ();
should be the same as require strict;
, just at run time, because nothing is imported.
$ perl -e 'require strict; $foo = 1'
This doesn't crash. But then at runtime you cannot turn on stuff that is supposed to be set at compile time.
So what does this actually do? When Perl reaches my actual code, it probably already encountered the strict
pragma somewhere else, so it wouldn't load it again. And it doesn't import anything.
$ perl -e 'print %INC'
Oops. This prints nothing. %INC
is empty. But if we use another module, there is something in it.
$ perl -MData::Dumper -e 'print Dumper \%INC'
$VAR1 = {
'warnings.pm' => '/usr/share/perl/5.22/warnings.pm',
'overload.pm' => '/usr/share/perl/5.22/overload.pm',
'Carp.pm' => '/usr/share/perl/5.22/Carp.pm',
'strict.pm' => '/usr/share/perl/5.22/strict.pm',
'overloading.pm' => '/usr/share/perl/5.22/overloading.pm',
'constant.pm' => '/usr/share/perl/5.22/constant.pm',
'bytes.pm' => '/usr/share/perl/5.22/bytes.pm',
'Data/Dumper.pm' => '/usr/lib/x86_64-linux-gnu/perl/5.22/Data/Dumper.pm',
'XSLoader.pm' => '/usr/share/perl/5.22/XSLoader.pm',
'Exporter.pm' => '/usr/share/perl/5.22/Exporter.pm',
'warnings/register.pm' => '/usr/share/perl/5.22/warnings/register.pm'
};
If we load Data::Dumper, strict
was loaded at some point. But not in the pure -e
example.
$ perl -e 'use strict (); print %INC'
strict.pm/usr/share/perl/5.22/strict.pm
Ok. This loads strict.pm.
$ perl -e 'require strict; print %INC'
strict.pm/usr/share/perl/5.22/strict.pm
So does that. But still, none of the strict
things are enabled.
So the question really is, is use strict ()
equivalent to just not having a use strict
statement at all, or is there something else happening?
1) perldoc strict refers to the three different arguments strict
can take as things
use strict ();
(essentially) doesn't do anything: see the docs:
If you do not want to call the package's import method (for instance, to stop your namespace from being altered), explicitly supply the empty list:
use Module ();
That is exactly equivalent to
BEGIN { require Module }
Of course, strict
only does something if you call its import
method (which you can easily verify by reading its source code; it's only about 150 lines long). So bypassing the import
method bypasses the entire effect of use strict
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With