如何在 perl 中正确使用全局变量 [英] How to properly use Global variables in perl

查看:113
本文介绍了如何在 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆