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.
I wrote the following:
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.
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?
Global variables can be used inside any function or any block created within the program. It is visible in the whole program. Global variables can directly use and are accessible from every part of the program. Example 1: The variable $name is declared at the beginning of the code.
In these cases the value of $@ is the compile error, or the argument to die.
$$ The process number of the perl running this script. (Mnemonic: same as shells.) $? The status returned by the last pipe close, backtick (\`\`) command or system operator.
The most commonly used special variable is $_, which contains the default input and pattern-searching string. For example, in the following lines − #!/usr/bin/perl foreach ('hickory','dickory','doc') { print $_; print "\n"; }
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
And then inside the subroutine:
sub ArgParser {
my ($sqluser, $sqlpass) = @_;
...
This way, your variables are nicely encapsulated and safe from being manipulated accidentally.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With