Avoiding errors with perl command line options and using strict

Why is my code not working after I add use strict; use warnings; use strict; use warnings; ? Is there any way to make it work?

Earlier working code:

 #!/usr/bin/perl -s print "x: $x\n"; print "y: $y\n"; 

The command I ran is perl -s test.pl -x="hello" -y="world" . Exit:

 x: hello y: world 

However, after adding use strict; use warnings; use strict; use warnings; I got the following errors:

 Variable "$x" is not imported at test.pl line 4. Variable "$y" is not imported at test.pl line 5. Global symbol "$x" requires explicit package name at test.pl line 4. Global symbol "$y" requires explicit package name at test.pl line 5. Execution of test.pl aborted due to compilation errors. 

I know that I need to declare my $x and my $y to fix the third and fourth errors. But what do the first 2 errors mean and how to overcome them?

+6
source share
3 answers

The rudimentary parser switch perl -s is used, which uses global variables. To make it work with use strict , you need to access the globals: $main::x , as Ruach pointed out.

But even in this case, lexical variables (declared with the help of my ) are preferred in almost all cases. Just do:

 use strict; use warnings; my ($x, $y) = @ARGV; print "x: $x\n"; print "y: $y\n"; 

And use with:

 perl test.pl hello world 

For more detailed and similar processing, go to Getopt :: Long .

+4
source

In fact, declaring these variables as lexical ( my ) variables will not help, because it is too late: the -s has already set them. It sets global (batch) variables (in your case $main::x and $main::y , or - as a special abridged version of $::x and $::y ). If you do not want to refer to them using your names defined in the package, then you can use our declaration to indicate that the bare names $x and $y refer to $x and $y in the current package:

 our ($x, $y); print "x: $x\n"; print "y: $y\n"; 

(Hat-tip to derobert for using our for this.)

In addition, you can copy global variables to lexical variables with the same name:

 my ($x, $y) = ($::x, $::y); print "x: $x\n"; print "y: $y\n"; 

This will take care of all diagnostic kits.

+9
source

To understand what ANY Perl error / warning means, you can refer to perldiag .

In particular, for "not imported," he says:

Variable '% s' is not imported% s

(W misc). Using "use strict", you are referencing a global variable that you apparently imported from another module because this module exports something of the same name (usually a subroutine). This usually means that you put the wrong funny character in front of your variable.

Basically, Perl made two different guesses about your declared identifier $x - it was either

  • a global package that is not allowed to be used in strict ("The global character" $ x "requires an explicit package")

  • or this is an attempt to use another package variable that should be imported but not ("Variable" $ x "not imported").

Perl cannot say which of the two theories is correct, so he spat out both possibilities. The last error (the global character "$ x" requires an explicit package name) was correct in this case - it was a global variable in your source pre-strict code.

+2
source

Source: https://habr.com/ru/post/910132/


All Articles