我是perl的新手.我试图通过编写一些程序来理解它.在perl中确定范围让我很难过.
我写了以下内容:
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"; } }
我的理解是,我们会将这些声明为主代码和子程序的全局变量.但是,这给出了以下输出:
#~/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,而宁愿将它们用作全局变量.有人可以帮我确定我对范围界定的误解吗?
解决方法
调用子例程时,不会声明变量:
&ArgParser; # subroutine call our ($sqluser,$sqlpass); # declaration $sqluser="root"; # assignment $sqlpass="mypassword";
为了在子例程中使用这些全局变量,将子例程放在变量声明之后.
但是,使用全局变量是一件坏事,您应该尽可能避免使用它.你可以这样做,例如:
my $sqluser = "root"; my $sqlpass = "mypass"; ArgParser($sqluser,$sqlpass); # you should not use & in subroutine calls
然后在子程序内:
sub ArgParser { my ($sqluser,$sqlpass) = @_; ...
这样,您的变量就可以很好地封装,并且不会被意外操作.
关于&符号&在子程序调用中,这在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.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。