Je sais ce qu'il my
y a en Perl. Il définit une variable qui n'existe que dans la portée du bloc dans lequel elle est définie. Que fait our
-on?
En quoi our
diffère- my
t-il de ?
Grande question: en quoi our
diffère- t -il my
et que fait our
-il?
En résumé:
Disponible depuis Perl 5, my
est un moyen de déclarer des variables non-package, qui sont:
$package_name::variable
.D'autre part, les our
variables sont des variables de package, et donc automatiquement:
$package_name::variable
.Déclarer une variable avec our
vous permet de prédéclarer des variables afin de les utiliser sous use strict
sans recevoir d'avertissements de frappe ou d'erreurs de compilation. Depuis Perl 5.6, il a remplacé le use vars
périmètre obsolète , qui était uniquement défini par fichier, et non lexicalement tel quel our
.
Par exemple, le nom formel et qualifié de la variable à l' $x
intérieur package main
est $main::x
. La déclaration our $x
vous permet d'utiliser la $x
variable nue sans pénalité (c'est-à-dire sans erreur résultante), dans le cadre de la déclaration, lorsque le script utilise use strict
ou use strict "vars"
. La portée peut être un, deux ou plusieurs packages, ou un petit bloc.
local
ne crée pas de variables. Cela ne concerne pasmy
etour
du tout.local
sauvegarde temporairement la valeur de la variable et efface sa valeur actuelle.our
les variables ne sont pas des variables de package. Ce ne sont pas des variables à portée globale, mais des variables à portée lexique, tout comme desmy
variables. Vous pouvez voir que dans le programme suivant:package Foo; our $x = 123; package Bar; say $x;
. Si vous souhaitez "déclarer" une variable de package, vous devez utiliseruse vars qw( $x );
.our $x;
déclare une variable de portée lexicale qui a un alias sur la variable du même nom dans le package dans lequel aour
été compilé.Les liens PerlMonks et PerlDoc de cartman et Olafur sont une excellente référence - voici ma fissure en un résumé:
my
les variables ont une portée lexicale dans un seul bloc défini par{}
ou dans le même fichier si ce n'est pas dans{}
s. Ils ne sont pas accessibles à partir des packages / sous-programmes définis en dehors du même champ / bloc lexical.our
les variables sont étendues dans un package / fichier et sont accessibles à partir de tout code quiuse
ou derequire
ce package / fichier - les conflits de nom sont résolus entre les packages en ajoutant l'espace de noms approprié.Pour arrondir, les
local
variables ont une portée «dynamique», ce qui diffère desmy
variables en ce qu'elles sont également accessibles à partir de sous-programmes appelés dans le même bloc.la source
my
variables ont une portée lexicale [...] dans le même fichier sinon dans{}
s". Cela m'a été utile, merci.Un exemple:
la source
Faire face à la portée est un bon aperçu des règles de portée de Perl. Il est assez ancien pour
our
ne pas être abordé dans le corps du texte. Il est abordé dans la section Notes à la fin.L'article parle des variables de package et de la portée dynamique et en quoi cela diffère des variables lexicales et de la portée lexicale.
la source
my
est utilisé pour les variables locales, alors qu'ilour
est utilisé pour les variables globales.Plus de lecture sur la portée variable en Perl: les bases .
la source
${^Potato}
est mondial. Il fait référence à la même variable quel que soit l'endroit où vous l'utilisez.J'ai déjà rencontré des pièges sur les déclarations lexicales en Perl qui m'ont dérangé, qui sont également liés à cette question, alors j'ajoute simplement mon résumé ici:
1. Définition ou déclaration?
La sortie est
var: 42
. Cependant, nous ne pouvons pas dire s'illocal $var = 42;
s'agit d'une définition ou d'une déclaration. Mais que diriez-vous de ceci:Le deuxième programme lancera une erreur:
$var
n'est pas défini, ce qui signifielocal $var;
est juste une déclaration! Avant d'utiliserlocal
pour déclarer une variable, assurez-vous qu'elle est préalablement définie comme une variable globale.Mais pourquoi cela n'échouera pas?
La sortie est:
var: 42
.C'est parce
$a
que, ainsi que$b
, est une variable globale prédéfinie en Perl. Vous vous souvenez de la fonction de tri ?2. Lexique ou global?
J'étais programmeur C avant de commencer à utiliser Perl, donc le concept de variables lexicales et globales me semble simple: il correspond juste aux variables auto et externes en C.Mais il y a de petites différences:
En C, une variable externe est une variable définie en dehors de tout bloc fonctionnel. D'autre part, une variable automatique est une variable définie à l'intérieur d'un bloc fonction. Comme ça:
En Perl, les choses sont subtiles:
La sortie est
var: 42
.$var
est une variable globale même si elle est définie dans un bloc fonction! En fait, en Perl, toute variable est déclarée globale par défaut.La leçon est de toujours ajouter
use strict; use warnings;
au début d'un programme Perl, ce qui forcera le programmeur à déclarer la variable lexicale explicitement, afin que nous ne soyons pas dérangés par certaines erreurs prises pour acquises.la source
Le perldoc a une bonne définition de notre.
la source
Ceci n'est que quelque peu lié à la question, mais je viens de découvrir un peu (pour moi) obscur de syntaxe Perl que vous pouvez utiliser avec "nos" variables (package) que vous ne pouvez pas utiliser avec "my" (local) variables.
Production:
Cela ne fonctionnera pas si vous remplacez «notre» par «mon».
la source
perl -e "my $foo = 'bar'; print $foo; ${foo} = 'baz'; pr int $foo"
output:barbaz
perl -e "my $foo = 'bar'; print $foo; ${"foo"} = 'baz'; print $foo"
output:barbaz
perl -e "my $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo"
output:barbar
Donc, lors de mes tests, j'étais tombé dans le même piège. $ {foo} est identique à $ foo, les crochets sont utiles lors de l'interpolation. $ {"foo"} est en fait une recherche vers $ main :: {} qui est la table de symboles principale, en tant que telle ne contient que des variables de portée du package.perl -e "package test; our $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo"
, car dans ce contexte $ {"foo"} est maintenant égal à $ {"test :: foo"}. Of Symbol Tables and Globs contient des informations à ce sujet, tout comme le livre de programmation Advanced Perl. Désolé pour mon erreur précédente.Sortira ceci:
Dans le cas où l'utilisation de "use strict" obtiendra cet échec lors de la tentative d'exécution du script:
la source
Essayez simplement d'utiliser le programme suivant:
la source
la source
our
etmy
différent? Comment cet exemple le montre-t-il?Pensons à ce qu'est réellement un interpréteur: c'est un morceau de code qui stocke des valeurs en mémoire et laisse les instructions d'un programme qu'il interprète accéder à ces valeurs par leurs noms, qui sont spécifiés dans ces instructions. Ainsi, le gros travail d'un interprète est de façonner les règles sur la façon dont nous devrions utiliser les noms dans ces instructions pour accéder aux valeurs stockées par l'interpréteur.
En rencontrant "mon", l'interpréteur crée une variable lexicale: une valeur nommée à laquelle l'interpréteur ne peut accéder que pendant qu'il exécute un bloc, et uniquement à partir de ce bloc syntaxique. En rencontrant "notre", l'interpréteur crée un alias lexical d'une variable de package: il lie un nom, que l'interpréteur est supposé désormais traiter comme le nom d'une variable lexicale, jusqu'à ce que le bloc soit terminé, à la valeur du package variable avec le même nom.
L'effet est que vous pouvez alors prétendre que vous utilisez une variable lexicale et contourner les règles de «use strict» sur la qualification complète des variables de package. Puisque l'interpréteur crée automatiquement des variables de package lors de leur première utilisation, l'effet secondaire de l'utilisation de "notre" peut également être que l'interpréteur crée également une variable de package. Dans ce cas, deux choses sont créées: une variable de package, à laquelle l'interpréteur peut accéder de partout, à condition qu'elle soit correctement désignée comme demandé par 'use strict' (précédée du nom de son package et de deux deux-points), et son alias lexical.
Sources:
la source