Comment utiliser correctement les variables Globales en perl
Je suis un novice de perl. Je suis en train d'essayer de le comprendre par l'écriture de certains programmes. La portée dans perl est de me donner un moment difficile.
J'ai écrit ce qui suit:
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";
}
}
C'était ma compréhension que notre permettrait de déclarer des variables globales pour l'utilisation du code principal et des sous-routines. Toutefois, cela donne le résultat suivant:
#~/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.
Je ne voudrais pas passer ces arguments pour les sous, mais de les utiliser comme des variables globales. Quelqu'un pourrait-il m'aider à déterminer mon incompréhension de la portée?
Vous exécutez des scripts perl en tant que root sans savoir exactement ce que vous faites? 🙂
Eh bien, oui, mais c'est un VPS sur lequel je ne fais rien d'autre que perl test, et de télécharger des torrents. 🙂
Pourtant, sa petite précaution de sécurité pour créer un nouvel utilisateur avec des privilèges limités.
Eh bien, oui, mais c'est un VPS sur lequel je ne fais rien d'autre que perl test, et de télécharger des torrents. 🙂
Pourtant, sa petite précaution de sécurité pour créer un nouvel utilisateur avec des privilèges limités.
OriginalL'auteur Joel G Mathew | 2013-04-16
Vous devez vous connecter pour publier un commentaire.
Vos variables ne sont pas déclarées lors de votre sous-routine est appelée:
Afin d'utiliser ces variables globales à l'intérieur de la sous-routine, mettez la sous-routine après la déclaration de la variable.
Cependant, l'utilisation de variables globales est une mauvaise chose, et vous devez les éviter autant que possible. Vous pouvez faire ceci au lieu de cela, par exemple:
Et puis à l'intérieur de la sous-routine:
De cette façon, vos variables sont joliment encapsulé et sûr d'être manipulé par hasard.
Concernant l'esperluette
&
dans votre sous-routine d'appel, ceci est documenté dans perldoc perlsub:C'est parce que vous n'avez pas lu la documentation que j'ai si soigneusement collé dans ma réponse pour vous.
ArgParser;
n'est pas dans la liste des moyens valables pour appeler une sous-routine, sauf si vous predeclare la sous-routine. UtilisationArgParser()
, avec des parenthèses.Désolé, je comprends maintenant. J'ai été à l'aide des sous-marins, sans le déclarer depuis quelques temps.
Vous avez seulement besoin de predeclare si vous voulez être en mesure d'utiliser les sous sans parenthèses. Donc, c'est pas mal.
Même si vous ne voulez pas passer à passer des arguments (et vous devriez vraiment faire le changement), vous pouvez toujours changer votre routine d'appel de
&ArgParser
àArgParser()
.OriginalL'auteur TLP
Perl n'a pas mondiale variables. Ce que Perl a sont:
Un package est un espace de noms. En Perl, un espace de noms est parfois appelé une paquet. Votre package par défaut le nom est
main
. Par exemple. C'est parfaitement légal:J'ai simplement préfixe mon paquet de noms de variables avec un paquet, et paf! Ils existent!
Ceci me cause la consternation:
Avec le
use strict;
, vous devez déclarer une variable commeour
oumy
, ou faites-le précéder du nom de la paquet.Variables de Package sont les plus faciles à comprendre. Les variables de Package sont en fait stockées dans une variable Perl structure, de sorte qu'ils sont toujours disponibles une fois déclaré:
Lexicalement d'étendue variables sont plus difficiles à comprendre. Fondamentalement, un lexicalement d'étendue variable est dans la portée de la bloc il est défini, mais hors de portée une fois que vous quittez le bloc. Il est également disponible dans les sous-blocs:
Voici quelques suggestions:
my
variables, et ils seront disponibles dans votre sous-routines depuis qu'ils sont encore dans le champ d'application.&
hors de sous-programme d'appels. Ils provoquer des changements subtils dans la façon dont le sous-programme de travaux et de ces changements subtils sont probablement pas ce que vous voulez. La norme, c'est juste pour appeler le sous-programme.? ... : ...
, surtout si vous n'utilisez pas d'espaces. Il rend votre programme plus difficile à lire, et ne pas enregistrer les temps d'exécution.my
variables de travail, mais les constantes de vous assurer que ces valeurs ne sera pas accidentellement changé dans votre programme.Voici votre code réécrit. Notez que les constantes de ne pas avoir un sceau en face. Ces ne peuvent normalement pas être interpolées dans les chaînes. Toutefois, si vous entourent avec
@{[...]}
, vous pouvez interpoler trop. J'ai fait les deux méthodes ci-dessous:OriginalL'auteur David W.
Un classique de ressources sur la variable de portée, dont je recommande la lecture, est L'adaptation à la portée par Mark-Jason Dominus: il décrit les fondamentaux de la partition dans les familles de Perl variables (paquet et lexicales variables) et met en garde contre certaines mauvaises pratiques d'un débutant pourrait être engagée dans.
Plutôt que obsolètes, je serais tout simplement dire qu'il est vieux: il manque les dernières nouvelles choses à propos de Perl, mais je pense que c'est encore valable dans sa substance. Quelque chose qu'il vaut la peine de lire, disons.
our
n'est pas vraiment nouveau, Il a été en Perl depuis 5.6.0 en 2000.OriginalL'auteur larsen