my perl script is:
#!/usr/bin/perl -w
use strict ;
use warnings;
print "Hello $name \n"
I get this error:
Global symbol "$name" requires explicit package name at fst_pscpt.pl.
This is really stopping my progress.do we need to include any packages???
Thanks & Regards,
B.Raviteja
You haven't declared any variable $name. So you'll need to get that variable somehow. For example, if you wanted to get it from the command line, you could do this:
#!/usr/bin/perl -w
use strict;
use warnings;
my $name = $ARGV[0];
print "Hello, $name!\n";
And then call your program like so:
./myprog.pl Rafe
And get the output:
Hello, Rafe!
Also, you don't have a semicolon at the end of the last line. You'll need that as well.
diagnostics gives you more useful help in this case:
$ perl -Mdiagnostics fst_pscpt.pl
Global symbol "$name" requires explicit package name at fst_pscpt.pl line 4.
Execution of fst_pscpt.pl aborted due to compilation errors (#1)
(F) You've said "use strict" or "use strict vars", which indicates
that all variables must either be lexically scoped (using "my"),
declared beforehand using "our", or explicitly qualified to say
which package the global variable is in (using "::").
Uncaught exception from user code:
Global symbol "$name" requires explicit package name at fst_pscpt.pl line 4.
Execution of fst_pscpt.pl aborted due to compilation errors.
at fst_pscpt.pl line 5
You need to declare $name when you use strict; (which includes strict vars). Just insert the line:
my $name;
before using it.
Related
I have a file which accepts a file as an argument and does some operation on it.
#!/usr/bin/perl
use strict;
use warnings;
use Date::Format;
use Pod::Usage;
###################
#USAGE
###################
=head1 SYNOPSIS
perl my-file.pl <log file name>
Options:
-help Prints usage synopsis of this program.
-man Man page for this program.
Use option "-man" for extended usage help.
=head1 ARGUMENTS
=over 1
=item 1 Log File Name
Enter name of the log file. This is a required argument.
=cut
print "\n\n";
GetOptions('help|?' => \$help, man => \$man) or pod2usage(2);
pod2usage(1) if $help;
pod2usage(-verbose => 2) if $man;
pod2usage("$0: Insufficient arguments given. Please see the usage below...") if (#ARGV == 0);
my $logfile = $ARGV[0];
my $cmd;
my $n;
$cmd = q(awk '!/Jobs still running./' $logfile > temp.txt && mv temp.txt $logfile);
$n = system($cmd)
;
While running this file I am getting the below compilation error. Not sure what is the reason for this error as another file with similar format work fine.
Global symbol "$help" requires explicit package name at mv-workitem-LogWatcher.pl line 33.
Global symbol "$man" requires explicit package name at mv-workitem-LogWatcher.pl line 33.
Global symbol "$help" requires explicit package name at mv-workitem-LogWatcher.pl line 34.
Global symbol "$man" requires explicit package name at mv-workitem-LogWatcher.pl line 35.
my-file.pl had compilation errors
.
You turned on strict but failed to declare your variables. You usually do this with my. Here's some more about my and lexical scoping of variables.
I'd recommend picking up a copy of Modern Perl or Beginning Perl.
You are getting errors because you are using use strict in your code but you didn't declare any varibale.
To understand variable declaration read this tutorial Variable declaration in Perl.
I've moved part of a script into a module, and now the only error I get when I do something wrong is "Undefined subroutine", even when the real error is that I misspelled a variable, or forgot a closing paren, or left off a semi-colon.
The only way to find the real error is to copy the entire thing into a script and run it that way. It's very tedious. Am I doing something wrong, or is this just the way modules are supposed to work?
Here is a very simple example that shows the problem:
Module:
#!/usr/bin/env perl
package CalledError;
use Exporter qw(import);
our #EXPORT_OK=qw(do_build_stor_pools);
use strict;
use warnings;
use feature qw(say);
sub do_build_stor_pools {
say "now in CalledError do_build_stor_pools";
#my $undef_var="uncomment this to fix";
say $undef_var;
return;
}
Calling script:
#!/usr/bin/env/perl
use strict;
use warnings;
my $buildstor_mod="CalledError";
eval "require $buildstor_mod";
$buildstor_mod->import();
CalledError::do_build_stor_pools();
Run it like this to get
Undefined subroutine &CalledError::do_build_stor_pools called at calling_test.pl line 11.
Uncomment the definition of $undef_var to make it work.
If you checked $EVAL_ERROR, you would see the real error:
#!/usr/bin/env/perl
use strict;
use warnings;
my $buildstor_mod="CalledError";
eval "require $buildstor_mod";
if ($#) {
die "$#";
}
$buildstor_mod->import();
CalledError::do_build_stor_pools();
Error message:
Global symbol "$undef_var" requires explicit package name at CalledError.pm line 15.
Compilation failed in require at (eval 1) line 2.
You see the undefined subroutine error because require fails.
You're not checking the error condition of your eval:
eval "require $buildstor_mod";
die $# if $#;
However, to load a module, you should just use use:
use strict;
use warnings;
use CalledError qw(do_build_stor_pools);
do_build_stor_pools();
Outputs:
Global symbol "$undef_var" requires explicit package name at CalledError.pm line 14.
I am trying to use the following conventions I have been instructed to use for good/proper/safe Perl code for my "Hello, World!" Program:
use strict;
use warnings;
I have created and successfully run the following "Hello World" program using (Strawberry) Perl 5.12 on my main Windows 7 OS:
!#/usr/bin/perl
use strict;
use warnings;
print "Hello, World!\n";
What I got back, as expected, was "Hello, World!".
What struck me as very odd was that the same program run in terminal on my virtualized Linux Mint 14 OS, using Perl 5.14, produced the following error:
"use" not allowed in expression at /PATH/hello_world.pl line 2, at end of line
syntax error at /PATH/hello_world.pl line 2, near "use strict"
BEGIN not safe after errors--compilation aborted at /PATH/hello_world.pl line 3.
I created other "Hello World" programs subsequently without either the use strict; or use warnings; lines, and also one with the -w, which I had seen in some tutorials, indicating, if I am not mistaken, that warnings would be turned on.
Both of my alternate versions worked properly in that they produced my expected result:
Hello, World!
What I cannot be sure of is if I need the use statements in Perl programs from version 5.14 and up or if it is just fine to write the -w at the end of my first line.
I would like to think that I could use a consistent header, so to speak, in all of my Perl programs, whether they are Windows or Linux, Perl 5.12 or 5.14 or otherwise.
Your image shows that all of your scripts start with !#/usr/bin/perl. This is wrong. It is not a valid she-bang line, it is read as negation ! followed by a comment #. The parsing will continue and with script1.pl perl will execute ! print "Hello world.\n";. This will print Hello world and negate the result of print ... not really useful, but valid perl.
In script2.pl perl sees ! use strict; and this is a compile time error and therefor perl fails and reports the error for the line use strict;.
So if you use correct she-bang lines, all three scripts will work as designed.
Edit (test scripts added):
script1.pl
!#/usr/bin/perl
print "Hello world.\n" ;
Calling perl script1.pl gives
Hello world.
script2.pl
!#/usr/bin/perl
use strict;
use warnings ;
print "Hello world.\n" ;
Calling perl script2.pl gives
"use" not allowed in expression at script2.pl line 3, at end of line
syntax error at script2.pl line 3, near "use strict "
BEGIN not safe after errors--compilation aborted at script2.pl line 4.
Using the correct syntax script3.pl
#!/usr/bin/perl
use strict ;
use warnings ;
print "Hello world.\n" ;
Calling perl script3.pl gives
Hello world.
You did something like
use warnings
use strict;
instead of
use warnings;
use strict;
Actually, I think it might be a line ending issue. You have LF where you should have CR LF or vice-versa. I've seen this cause Perl to think the code starts halfway through the shebang line (e.g. perl use strict;)
As mentioned elsewhere, the code you posted and the code you used is different. You actually used
!use strict;
due to a bad shebang line.
!#/u... # Negation followed by a comment
should be
#!/u... # Shebang
I have a huge system that I'm converting from a cgi to a daemon and I need to find all the variables that end up being global (as in not declared with my $...)
They are probably intended to be scoped locally, but in perl if you accidentally forget, it doesn't care, but now I do.
I gotta figure the perl interpreter can tell the difference, so is there a way to get it to tell me? I could go through all the code by hand, looking for declarations, but there thousands and thousands and thousands of lines of code in this system.
perldoc strict will show all variables not declared with my:
$ perl -Mstrict=vars -c -e '$x=5; my $y=7; $z=6;'
Global symbol "$x" requires explicit package name at -e line 1.
Global symbol "$z" requires explicit package name at -e line 1.
-e had compilation errors.
The same thing with a list of files:
$ perl -Mstrict=vars -c *.pl
Here is another way using perldoc B::Xref
$ perl -MO=Xref -e '$x=5; my $y=7; $z=6;'
... lots of verbose output
Subroutine (main)
Package (lexical)
$y i1
Package main
$x 1
$z 1
With the PadWalker Module you can see all variables in a specific scope. You can see variables declared with "my" and "our".
You should still use "use strict" but using "use strict" does not show you global variables that you declare as global.
For example this example still has a global variable and strict does not do anything
#!/usr/bin/env perl
use strict;
use warnings;
our $foo;
With PadWalker you can use something like this.
#!/usr/bin/env perl
use strict;
use warnings;
use DDP;
use PadWalker qw(peek_our);
our $var;
print p peek_our(0);
The output is
\ {
$var \ undef
}
Sure, you only should use PadWalker for Debugging.
I am pretty layman to Perl, never used it ...but now I want to use it.
Here is what I did:
http://www.activestate.com/activeperl/downloads
I installed universal version - 5.12.4.1205
To test my program is working, I used the following small program :
dnacon.plx
#i/Perl64/bin/perl -w
#Example 1-1 Concatenating DNA
$DNA1 = 'ATTTGGTAAAATGTATA'
$DNA2 = 'TTTTGGGTTTGAAAT'
print "Here are two DNA fragments: \n\n"
print $DNA1, "\n\n"
print $DNA2, "\n\n"
$DNA3 = "$DNA1$$DNA2"
print "$DNA3\n\n
When I try to execute it the following is command prompt with errors.
Sorry for too basic question...
EDTIS:
When I just type dnacon.plx, it is seems that it is working, but with error !!!
c:\myperllessions>dnacon.plx
Scalar found where operator expected at C:\myperllessions\dnacon.plx line 5, nea
r "$DNA2"
(Missing semicolon on previous line?)
syntax error at C:\myperllessions\dnacon.plx line 5, near "$DNA2 "
Execution of C:\myperllessions\dnacon.plx aborted due to compilation errors.
Am I good to go ??? What could be the error ...compilation errors ????
Edits:
I am using the following now : is this correct ?
#i/Perl64/bin -w
Edits:
I changed my script to following:
#i/Perl64/bin -w
#Example 1-1 Concatenating DNA
use strict;
use warnings;
$DNA1 = 'ATTTGGTAAAATGTATA';
$DNA2 = 'TTTTGGGTTTGAAAT';
print "Here are two DNA fragments: \n\n";
print $DNA1, "\n\n";
print $DNA2, "\n\n";
$DNA3 = "$DNA1$$DNA2";
print "$DNA3\n\n";
I got the following error:
c:\myperllessions>dnacon.plx
Global symbol "$DNA1" requires explicit package name at C:\myperllessions\dnacon
.plx line 5.
Global symbol "$DNA2" requires explicit package name at C:\myperllessions\dnacon
.plx line 6.
Global symbol "$DNA1" requires explicit package name at C:\myperllessions\dnacon
.plx line 9.
Global symbol "$DNA2" requires explicit package name at C:\myperllessions\dnacon
.plx line 10.
Global symbol "$DNA3" requires explicit package name at C:\myperllessions\dnacon
.plx line 12.
Global symbol "$DNA1" requires explicit package name at C:\myperllessions\dnacon
.plx line 12.
Global symbol "$DNA2" requires explicit package name at C:\myperllessions\dnacon
.plx line 12.
Global symbol "$DNA3" requires explicit package name at C:\myperllessions\dnacon
.plx line 13.
Execution of C:\myperllessions\dnacon.plx aborted due to compilation errors.
Is my problem now with programming knowledge or something to do with installation ?????
To get perl to be recognized, you must add C:\Perl64\bin to the PATH environment variable. Go to Control Panel > System > Advanced System Settings > Environment Variables. Edit the line containing PATH in the top box marked User variables for <user>, and add ;C:\Perl64\bin (note the semicolon) to the end. Be sure not to corrupt anything that's already there.
The problems you are left with in your latest edit - Global symbol requires explicit package name - are because you have added use strict (a very good thing to do) and you haven't declared your variables. Also the line #i/Perl64/bin -w won't do anything and may as well be removed. Write this instead
use strict;
use warnings;
my $DNA1 = 'ATTTGGTAAAATGTATA';
my $DNA2 = 'TTTTGGGTTTGAAAT';
print "Here are two DNA fragments: \n\n";
print $DNA1, "\n\n";
print $DNA2, "\n\n";
my $DNA3 = "$DNA1$$DNA2";
print "$DNA3\n\n";
Did you try out Strawberry perl? It takes care of setting up the environment vars for you.
An environment variable may not be set up yet.
Since I no longer use Windows, I cannot give you the exact step by step instructions, but I can tell you, that somewhere in System Properties, you'll find a place to edit the environment variables.
Edit the path variable and append 'C:\Perl64\bin\' to it.
P.S.:This is assuming that when you cd to the said path, you are able to run the perl program. If not, something is wrong with the installation. Try re-installing Perl.