如何在 perl 中正确使用全局变量 [英] How to properly use Global variables in perl
问题描述
我是 perl 的新手.我试图通过编写一些程序来理解它.在 perl 中确定范围让我很困难.
I am a novice to perl. I'm trying to understand it by writing some programs. Scoping in perl is giving me a hard time.
我写了以下内容:
use 5.16.3;
use strict;
use Getopt::Long;
Getopt::Long::Configure(qw(bundling no_getopt_compat));
&ArgParser;
our ($sqluser,$sqlpass);
$sqluser="root";
$sqlpass="mypassword";
sub ArgParser {
print "Username is ".$sqluser." Password is ".$sqlpass."\n";
my $crt='';
my $delete='';
GetOptions ('create|c=s' => \$crt,
'delete|d=s' => \$delete
);
if ($crt) {
&DatabaseExec("create",$crt);
} elsif ($delete) {
&DatabaseExec("delete",$delete);
} else {
print "No options chosen\n";
}
}
sub DatabaseExec {
use DBI;
my $dbname=$_[1];
print "Username is ".$sqluser." Password is ".$sqlpass."\n";
my $dbh = DBI->connect("dbi:mysql:", $sqluser,$sqlpass);
my $comand=$_[0];
if ($_[0] eq "create") {
my $db_com="create database ".$dbname;
print 1 == $dbh->do($db_com) ? "Database created\n":"An error occured while creating database. Maybe it exists?\n";
#print "Executing: ".$db_com."\n";
} elsif ($_[0] eq "delete") {
my $db_com="DROP DATABASE ".$dbname;
#print "Executing: ".$db_com."\n";
print 1 == $dbh->do($db_com) ? "Database deleted\n":"An error occured while creating database. Maybe it exists?\n";
}
}
据我所知,我们会将这些声明为全局变量以供主代码和子程序使用.但是,这给出了以下输出:
It was my understanding that our would declare these as global variables for the use of the main code, and subroutines. However this gives the following output:
#~/perlscripts/dbtest.pl -c hellos
Use of uninitialized value $sqluser in concatenation (.) or string at /root/perlscripts/dbtest.pl line 20.
Use of uninitialized value $sqlpass in concatenation (.) or string at /root/perlscripts/dbtest.pl line 20.
Username is Password is
Use of uninitialized value $sqluser in concatenation (.) or string at /root/perlscripts/dbtest.pl line 44.
Use of uninitialized value $sqlpass in concatenation (.) or string at /root/perlscripts/dbtest.pl line 44.
Username is Password is
DBI connect('','',...) failed: Access denied for user 'root'@'localhost' (using password: NO) at /root/perlscripts/dbtest.pl line 45.
Can't call method "do" on an undefined value at /root/perlscripts/dbtest.pl line 50.
我不想将这些作为参数传递给 sub,而是将它们用作全局变量.有人可以帮我确定我对范围界定的误解吗?
I would not like to pass these as arguments to the sub, and would rather use them as global variables. Could someone help me determine my misunderstanding of scoping?
推荐答案
当你的子程序被调用时你的变量没有被声明:
Your variables are not declared when your subroutine is called:
&ArgParser; # subroutine call
our ($sqluser,$sqlpass); # declaration
$sqluser="root"; # assignment
$sqlpass="mypassword";
为了在子程序中使用这些全局变量,请将子程序放在变量声明之后.
In order to use these global variables inside the subroutine, put the subroutine after the variable declaration.
然而,使用全局变量是一件坏事,你应该尽可能避免它.您可以改为这样做,例如:
However, using global variables is a bad thing, and you should avoid it whenever possible. You can do this instead, for example:
my $sqluser = "root";
my $sqlpass = "mypass";
ArgParser($sqluser, $sqlpass); # you should not use & in subroutine calls
然后在子程序中:
sub ArgParser {
my ($sqluser, $sqlpass) = @_;
...
通过这种方式,您的变量被很好地封装并且不会被意外操作.
This way, your variables are nicely encapsulated and safe from being manipulated accidentally.
关于您的子程序调用中的 & 符号 &
,这在 perldoc perlsub 中有说明:
Regarding the ampersand &
in your subroutine call, this is documented in perldoc perlsub:
To call subroutines:
NAME(LIST); # & is optional with parentheses.
NAME LIST; # Parentheses optional if predeclared/imported.
&NAME(LIST); # Circumvent prototypes.
&NAME; # Makes current @_ visible to called subroutine.
这篇关于如何在 perl 中正确使用全局变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!