GoGPT Best VPN GoSearch

Icône de favori OnWorks

perlref - En ligne dans le Cloud

Exécutez perlref dans le fournisseur d'hébergement gratuit OnWorks sur Ubuntu Online, Fedora Online, l'émulateur en ligne Windows ou l'émulateur en ligne MAC OS

Il s'agit de la commande perlref qui peut être exécutée dans le fournisseur d'hébergement gratuit OnWorks en utilisant l'un de nos nombreux postes de travail en ligne gratuits tels que Ubuntu Online, Fedora Online, l'émulateur en ligne Windows ou l'émulateur en ligne MAC OS

PROGRAMME:

Nom


perlref - Références Perl et structures de données imbriquées

REMARQUE


Ceci est une documentation complète sur tous les aspects des références. Pour un tutoriel plus court,
introduction aux fonctionnalités essentielles, voir perlreftut.

DESCRIPTION


Avant la version 5 de Perl, il était difficile de représenter des structures de données complexes, car
toutes les références devaient être symboliques - et même dans ce cas, il était difficile de faire référence à une variable
au lieu d'une entrée dans la table des symboles. Perl simplifie désormais non seulement l'utilisation des symboles,
références à des variables, mais vous permet également d'avoir des références « dures » à n'importe quel élément de données ou
code. Tout scalaire peut contenir une référence physique. Puisque les tableaux et les hachages contiennent des scalaires,
vous pouvez désormais facilement créer des tableaux de tableaux, des tableaux de hachages, des hachages de tableaux, des tableaux de
hachages de fonctions, etc.

Les références matérielles sont intelligentes : elles enregistrent automatiquement le nombre de références pour vous.
libérer la chose référencée lorsque son nombre de références atteint zéro. (Nombre de références
pour les valeurs dans les structures de données autoréférentielles ou cycliques ne peuvent pas aller à zéro sans un
peu d'aide ; voir « Références circulaires » pour une explication détaillée.) Si cette chose se produit
pour être un objet, l'objet est détruit. Voir perlobj pour en savoir plus sur les objets. (Dans un
En Perl, tout est un objet, mais nous réservons généralement ce mot aux références à
objets qui ont été officiellement « bénis » dans un package de classe.)

Les références symboliques sont des noms de variables ou d’autres objets, tout comme un lien symbolique dans un
Le système de fichiers Unix contient simplement le nom d'un fichier. La notation *glob est une sorte de
référence symbolique. (Les références symboliques sont parfois appelées « références souples », mais
s'il vous plaît, ne les appelez pas ainsi ; les références sont déjà assez confuses sans synonymes inutiles.)

En revanche, les références matérielles ressemblent davantage à des liens matériels dans un système de fichiers Unix : elles sont utilisées
d'accéder à un objet sous-jacent sans se soucier de son (autre) nom. Lorsque le
le mot « référence » est utilisé sans adjectif, comme dans le paragraphe suivant, il est
on parle généralement d'une référence dure.

Les références sont faciles à utiliser en Perl. Un seul principe prévaut : en général,
Perl n'effectue aucun référencement ni déréférencement implicite. Lorsqu'un scalaire contient une référence,
Il se comporte toujours comme un simple scalaire. Il ne se transforme pas par magie en tableau ou en hachage.
ou sous-routine ; vous devez lui dire explicitement de le faire, en le déréférençant.

Cela dit, sachez que la version 5.14 de Perl introduit une exception à la règle, par
commodité syntaxique. Le comportement expérimental des fonctions conteneurs de tableaux et de hachages permet
références de tableau et de hachage à gérer par Perl comme si elles avaient été explicitement
syntaxiquement déréférencé. Voir « Améliorations syntaxiques » dans perl5140delta et perlfunc.
pour en savoir plus.

Fabrication Références
Les références peuvent être créées de plusieurs manières.

1. En utilisant l'opérateur barre oblique inverse sur une variable, une sous-routine ou une valeur. (Cela fonctionne beaucoup
comme l'opérateur & (adresse de) en C.) Cela crée généralement une référence à un
variable, car il existe déjà une référence à la variable dans la table des symboles.
Mais la référence à la table des symboles pourrait disparaître, et vous aurez toujours la référence qui
la barre oblique inverse est renvoyée. Voici quelques exemples :

$scalarref = \$foo;
$arrayref = \@ARGV;
$hashref = \%ENV;
$coderef = \&handler;
$globref = \*foo;

Il n'est pas possible de créer une véritable référence à un handle d'E/S (filehandle ou dirhandle)
en utilisant l'opérateur barre oblique inverse. On peut obtenir au mieux une référence à un typeglob,
qui est en fait une entrée complète de la table des symboles. Mais voir l'explication de
Syntaxe *foo{THING} ci-dessous. Vous pouvez néanmoins utiliser des globs et des globrefs de type comme
même s'il s'agissait de poignées d'E/S.

2. Une référence à un tableau anonyme peut être créée à l'aide de crochets :

$arrayref = [1, 2, ['a', 'b', 'c']];

Ici, nous avons créé une référence à un tableau anonyme de trois éléments dont le final
L'élément est lui-même une référence à un autre tableau anonyme de trois éléments. (Le
La syntaxe multidimensionnelle décrite plus loin permet d'y accéder. Par exemple :
après ce qui précède, "$arrayref->[2][1]" aurait la valeur "b".)

Prendre une référence à une liste énumérée n'est pas la même chose qu'utiliser un carré
crochets - c'est plutôt la même chose que de créer une liste de références !

@list = (\$a, \@b, \%c);
@list = \($a, @b, %c); # même chose !

En tant que cas particulier, "\(@foo)" renvoie une liste de références au contenu de @foo, pas
une référence à @foo lui-même. De même pour %foo, sauf que les références clés sont à
copies (puisque les clés ne sont que des chaînes plutôt que des scalaires à part entière).

3. Une référence à un hachage anonyme peut être créée à l'aide d'accolades :

$hashref = {
'Adam' => 'Ève',
'Clyde' => 'Bonnie',
};

Les compositeurs de hachage et de tableau anonymes comme ceux-ci peuvent être mélangés librement pour produire autant
Vous pouvez complexifier une structure à votre guise. La syntaxe multidimensionnelle décrite ci-dessous
Cela fonctionne également pour ces cas-là. Les valeurs ci-dessus sont des littéraux, mais les variables et expressions
fonctionneraient tout aussi bien, car les opérateurs d'affectation en Perl (même dans locale() or
ma()) sont des instructions exécutables et non des déclarations au moment de la compilation.

Parce que les accolades sont utilisées pour plusieurs autres choses, y compris les BLOCS,
vous devrez peut-être parfois lever l'ambiguïté des accolades au début d'une instruction en
en mettant un « + » ou un « retour » devant pour que Perl réalise que l'accolade ouvrante n'est pas
démarrer un bloc. L'économie et la valeur mnémotechnique de l'utilisation des boucles sont jugées importantes.
ces tracas supplémentaires occasionnels.

Par exemple, si vous vouliez qu'une fonction crée un nouveau hachage et renvoie une référence à celui-ci,
vous avez ces options :

sous-hachage { { @_ } } # silencieusement faux
sous-hachage { +{ @_ } } # ok
sous-hachage {retour { @_}} # ok

D'un autre côté, si vous voulez l'autre sens, vous pouvez faire ceci :

sub showem { { @_ } } # ambigu (actuellement ok,
# mais peut changer)
sous-showem { {; @_ } } # ok
sous-showem { { return @_ } } # ok

Les préfixes « +{ » et « {; » servent toujours à lever l'ambiguïté de l'expression pour signifier soit
la référence HASH, ou le BLOCK.

4. Une référence à une sous-routine anonyme peut être créée en utilisant « sub » sans
sous-nom:

$coderef = sub { print "Boink!\n" };

Notez le point-virgule. À l'exception du code qui n'est pas immédiatement exécuté, un « sub »
{}" n'est pas tant une déclaration qu'un opérateur, comme "do{}" ou "eval{}".
(Cependant, peu importe le nombre de fois que vous exécutez cette ligne particulière (à moins que vous ne soyez dans
un "eval("...")"), $coderef aura toujours une référence au même anonyme
sous-routine.)

Les sous-routines anonymes agissent comme des fermetures par rapport à ma() variables, c'est-à-dire
variables lexicalement visibles dans la portée actuelle. La fermeture est une notion hors de la
Monde Lisp qui dit que si vous définissez une fonction anonyme dans un lexique particulier
contexte, il prétend s'exécuter dans ce contexte même lorsqu'il est appelé en dehors du contexte.

En termes humains, c'est une manière amusante de passer des arguments à une sous-routine lorsque vous définissez
et lorsque vous l'appelez. C'est utile pour configurer de petits morceaux de code à exécuter.
plus tard, comme les rappels. On peut même l'utiliser pour des tâches orientées objet, grâce à Perl.
fournit déjà un mécanisme différent pour faire cela - voir perlobj.

Vous pouvez également considérer la fermeture comme un moyen d’écrire un modèle de sous-routine sans utiliser
eval ()Voici un petit exemple du fonctionnement des fermetures :

sous-impression {
mon $x = décalage ;
retourner sous { mon $y = shift; imprimer "$x, $y!\n"; };
}
$h = newprint("Salut");
$g = newprint("Salutations");

# Le temps passe...

&$h("monde");
&$g("terriens");

Cette imprime

Salut le monde !
Salutations, terriens !

Notez particulièrement que $x continue de faire référence à la valeur transmise dans nouvelle impression()
malgré « mon $x » étant sorti du champ d'application au moment où la sous-routine anonyme s'exécute.
C'est à cela que sert une fermeture.

Ceci ne s'applique qu'aux variables lexicales, soit dit en passant. Les variables dynamiques continuent à
fonctionnent comme ils l'ont toujours fait. La fermeture n'est pas une option que la plupart des programmeurs Perl
ils n'ont pas besoin de se préoccuper de cela pour commencer.

5. Les références sont souvent renvoyées par des sous-routines spéciales appelées constructeurs. Perl
les objets ne sont que des références à un type spécial d'objet qui sait lequel
package auquel il est associé. Les constructeurs ne sont que des sous-routines spéciales qui savent comment
pour créer cette association. Ils le font en partant d'une référence ordinaire,
demeure une référence ordinaire même s'il est également un objet. Les constructeurs sont
souvent appelé « nouveau() ». Vous Vous pouvez appelez-les indirectement :

$objref = new Doggie( Queue => 'courte', Oreilles => 'longues' );

Mais cela peut produire une syntaxe ambiguë dans certains cas, il est donc souvent préférable d'utiliser
l'approche d'invocation directe de méthode :

$objref = Doggie->new(Queue => 'courte', Oreilles => 'longues');

utiliser Terme::Cap;
$terminal = Term::Cap->Tgetent( { OSPEED => 9600 });

utiliser Tk;
$main = MainWindow->nouveau();
$menubar = $main->Frame(-relief => "en relief",
-largeur de la bordure => 2)

6. Des références du type approprié peuvent apparaître si vous les déréférencez
dans un contexte qui suppose leur existence. Car nous n'avons pas parlé de déréférencement.
pour l'instant, nous ne pouvons pas encore vous montrer d'exemples.

7. Une référence peut être créée en utilisant une syntaxe spéciale, affectueusement connue sous le nom de
Syntaxe *foo{THING}. *foo{THING} renvoie une référence à l'emplacement THING dans *foo (qui
est l'entrée de la table des symboles qui contient tout ce qui est connu sous le nom de foo).

$scalarref = *foo{SCALAIRE};
$arrayref = *ARGV{TABLEAU};
$hashref = *ENV{HASH};
$coderef = *handler{CODE};
$ioref = *STDIN{IO};
$globref = *foo{GLOB};
$formatref = *foo{FORMAT};
$globname = *foo{NOM}; # "foo"
$pkgname = *foo{PACKAGE}; # "main"

La plupart d'entre eux sont explicites, mais *foo{IO} mérite une attention particulière.
renvoie le handle d'E/S, utilisé pour les handles de fichiers (« open » dans perlfunc), les sockets (« socket »
dans perlfunc et « socketpair » dans perlfunc), et les descripteurs de répertoire (« opendir » dans
perlfunc). Pour la compatibilité avec les versions précédentes de Perl, *foo{FILEHANDLE} est un
Synonyme de *foo{IO}, bien qu'il soit obsolète depuis la version 5.8.0. Si des avertissements d'obsolescence s'affichent,
sont en vigueur, il avertira de son utilisation.

*foo{THING} renvoie undef si cette CHOSE particulière n'a pas encore été utilisée, sauf dans le
cas de scalaires. *foo{SCALAR} renvoie une référence à un scalaire anonyme si $foo
Cette fonctionnalité n'a pas encore été utilisée. Cela pourrait changer dans une prochaine version.

*foo{NAME} et *foo{PACKAGE} sont l'exception, dans la mesure où ils renvoient des chaînes, plutôt que
que les références. Celles-ci renvoient le package et le nom du typeglob lui-même, plutôt que
que celui qui lui a été assigné. Ainsi, après « *foo=*Foo::bar », *foo deviendra
"*Foo::bar" lorsqu'il est utilisé comme chaîne, mais *foo{PACKAGE} et *foo{NAME} continueront à
produire respectivement « main » et « foo ».

*foo{IO} est une alternative au mécanisme *HANDLE donné dans « Typeglobs et
« Filehandles » dans perldata pour passer des fichiers dans ou hors des sous-routines, ou
stockage dans des structures de données plus grandes. Son inconvénient est qu'il ne crée pas de nouvelle
descripteur de fichier. Son avantage est que vous avez moins de risques de le détruire que
vous voulez avec une affectation typeglob. (Cela confond toujours fichier et répertoire
poignées, cependant.) Cependant, si vous attribuez la valeur entrante à un scalaire au lieu d'un
typeglob comme nous le faisons dans les exemples ci-dessous, il n'y a aucun risque que cela se produise.

splutter(*STDOUT); # passer le glob entier
splutter(*STDOUT{IO}); # passe les handles de fichier et de répertoire

sous-crachotement {
mon $fh = décalage ;
print $fh "elle euh bien un hmmm\n" ;
}

$rec = get_rec(*STDIN); # passer le glob entier
$rec = get_rec(*STDIN{IO}); # passe les handles de fichier et de répertoire

sous-get_rec {
mon $fh = décalage ;
renvoie le scalaire <$fh> ;
}

En utilisant Références
Voilà pour la création de références. Vous avez probablement hâte de savoir comment les utiliser.
Des références pour retrouver vos données perdues depuis longtemps. Il existe plusieurs méthodes de base.

1. Partout où vous placeriez un identifiant (ou une chaîne d'identifiants) dans le cadre d'une variable ou
nom de sous-routine, vous pouvez remplacer l'identifiant par une simple variable scalaire
contenant une référence du type correct :

$bar = $$scalarref;
push(@$arrayref, $filename);
$$arrayref[0] = "Janvier";
$$hashref{"CLÉ"} = "VALEUR";
&$coderef(1,2,3);
imprimer $globref "sortie\n";

Il est important de comprendre que nous sommes spécifiquement pas déréférencement de $arrayref[0]
ou $hashref{"KEY"} ici. La déréférence de la variable scalaire se produit. avant it
effectue des recherches de clés. Toute variable plus complexe qu'une simple variable scalaire doit
Utilisez les méthodes 2 ou 3 ci-dessous. Cependant, un « scalaire simple » inclut un identifiant qui
utilise lui-même la méthode 1 de manière récursive. Par conséquent, la commande suivante affiche « howdy ».

$refrefref = \\\"bonjour";
imprimer $$$$refrefref;

2. Partout où vous placeriez un identifiant (ou une chaîne d'identifiants) dans le cadre d'une variable ou
nom de sous-routine, vous pouvez remplacer l'identifiant par un BLOC renvoyant une référence de
le type correct. Autrement dit, les exemples précédents pourraient s'écrire ainsi :

$bar = ${$scalarref};
push(@{$arrayref}, $filename);
${$arrayref}[0] = "Janvier";
${$hashref}{"CLÉ"} = "VALEUR";
&{$coderef}(1,2,3);
$globref->print("output\n"); # si et seulement si IO::Handle est chargé

Certes, c'est un peu idiot d'utiliser les boucles dans ce cas, mais le BLOCK peut
contenir toute expression arbitraire, en particulier les expressions en indice :

&{ $dispatch{$index} }(1,2,3); # appeler la routine correcte

Parce qu'il est possible d'omettre les boucles pour le cas simple de $$x, les gens ont souvent
faire l'erreur de considérer les symboles de déréférencement comme des opérateurs appropriés et se demander
concernant leur priorité. Si c'était le cas, vous pourriez utiliser des parenthèses à la place de
accolades. Ce n'est pas le cas. Considérez la différence ci-dessous : le cas 0 est un raccourci.
version du cas 1, pas cas 2:

$$hashref{"KEY"} = "VALUE"; # CAS 0
${$hashref}{"KEY"} = "VALUE"; # CAS 1
${$hashref{"KEY"}} = "VALUE"; # CAS 2
${$hashref->{"KEY"}} = "VALUE"; # CAS 3

Le cas 2 est également trompeur dans la mesure où vous accédez à une variable appelée %hashref, et non
déréférencement via $hashref vers le hachage auquel il fait vraisemblablement référence. Ce serait
cas 3.

3. Les appels de sous-routines et les recherches d'éléments de tableau individuels se produisent suffisamment souvent pour qu'il
devient fastidieux d'utiliser la méthode 2. En tant que forme de sucre syntaxique, les exemples pour
la méthode 2 peut s'écrire :

$arrayref->[0] = "Janvier"; # Élément de tableau
$hashref->{"KEY"} = "VALUE"; # Élément de hachage
$coderef->(1,2,3); # Appel de sous-routine

Le côté gauche de la flèche peut être n'importe quelle expression renvoyant une référence, y compris une
déréférencement précédent. Notez que $array[$x] est pas la même chose que "$array->[$x]"
ici:

$array[$x]->{"foo"}->[0] = "Janvier";

C'est l'un des cas que nous avons mentionnés plus tôt dans lesquels des références pourraient surgir
dans un contexte lvalue. Avant cette instruction, $array[$x] était peut-être
indéfini. Si c'est le cas, il est automatiquement défini avec une référence de hachage afin que nous puissions
Recherchez « {"foo"} ». De même, « $array[$x]->{"foo"} » obtiendra automatiquement
défini avec une référence de tableau afin que nous puissions y rechercher « [0] ». Ce processus est
appelé l'autovivification.

Autre chose : la flèche est facultative. jusqu'à XNUMX fois crochets indices, afin que vous puissiez
réduire ce qui précède à

$array[$x]{"foo"}[0] = "Janvier";

Ce qui, dans le cas dégénéré d'utilisation de tableaux ordinaires uniquement, vous donne
tableaux multidimensionnels comme ceux de C :

$score[$x][$y][$z] += 42;

Bon, d'accord, ce n'est pas tout à fait comme les tableaux de C, en fait. C ne sait pas comment développer ses
tableaux à la demande. Perl le fait.

4. Si une référence se trouve être une référence à un objet, alors il existe probablement des méthodes
pour accéder aux choses mentionnées, et vous devriez probablement vous en tenir à ces méthodes
sauf si vous êtes dans le package de classe qui définit les méthodes de l'objet. Autrement dit,
soyez gentil et ne violez pas l'encapsulation de l'objet sans une très bonne raison.
Perl n'impose pas l'encapsulation. Nous ne sommes pas totalitaires ici. Nous attendons
un peu de civilité de base cependant.

L'utilisation d'une chaîne ou d'un nombre comme référence produit une référence symbolique, comme expliqué ci-dessus.
L'utilisation d'une référence comme nombre produit un entier représentant son emplacement de stockage dans
mémoire. La seule chose utile à faire avec cela est de comparer deux références
numériquement pour voir s'ils se réfèrent au même endroit.

si ($ref1 == $ref2) { # comparaison numérique bon marché de références
print "les références 1 et 2 font référence à la même chose\n";
}

L'utilisation d'une référence sous forme de chaîne produit à la fois le type de son référent, y compris tout package
bénédiction telle que décrite dans perlobj, ainsi que l'adresse numérique exprimée en hexadécimal.
réf() L'opérateur renvoie uniquement le type d'élément vers lequel pointe la référence, sans le
adresse. Voir « ref » dans perlfunc pour plus de détails et des exemples d'utilisation.

Le manuel de formation bénir() L'opérateur peut être utilisé pour associer l'objet vers lequel pointe une référence à un
Package fonctionnant comme une classe d'objets. Voir perlobj.

Un typeglob peut être déréférencé de la même manière qu'une référence, car la déréférence
La syntaxe indique toujours le type de référence souhaité. Ainsi, « ${*foo} » et « ${\$foo} »
indiquent la même variable scalaire.

Voici une astuce pour interpoler un appel de sous-routine dans une chaîne :

print "Mon abonnement a renvoyé @{[mysub(1,2,3)]} cette fois-là.\n";

Le fonctionnement est le suivant : lorsque le "@{...}" apparaît dans la chaîne entre guillemets, c'est
évalué comme un bloc. Le bloc crée une référence à un tableau anonyme contenant les
résultats de l'appel à « mysub(1,2,3) ». Le bloc entier renvoie donc une référence à une
tableau, qui est ensuite déréférencé par "@{...}" et collé dans la chaîne entre guillemets.
Cette astuce est également utile pour les expressions arbitraires :

imprimer "Cela donne @{[$n + 5]} widgets\n";

De même, une expression qui renvoie une référence à un scalaire peut être déréférencée via
« ${...} ». Ainsi, l'expression ci-dessus peut s'écrire :

imprimer "Cela donne ${\($n + 5)} widgets\n";

Circulaire Références
Il est possible de créer une « référence circulaire » en Perl, ce qui peut entraîner des fuites de mémoire.
une référence circulaire se produit lorsque deux références contiennent une référence l'une à l'autre, comme
ce:

mon $foo = {};
mon $bar = { foo => $foo };
$foo->{bar} = $bar;

Vous pouvez également créer une référence circulaire avec une seule variable :

mon $foo ;
$foo = \$foo;

Dans ce cas, le nombre de références pour les variables n'atteindra jamais 0, et les références
ne sera jamais récupéré par le ramasse-miettes. Cela peut entraîner des fuites de mémoire.

Étant donné que les objets en Perl sont implémentés comme des références, il est possible d'avoir des objets circulaires.
références avec des objets également. Imaginez une classe TreeNode où chaque nœud référence son
Nœuds parents et enfants. Tout nœud ayant un parent fera partie d'une référence circulaire.

Vous pouvez rompre les références circulaires en créant une « référence faible ». Une référence faible ne
ne pas incrémenter le nombre de références pour une variable, ce qui signifie que l'objet peut sortir
hors de portée et être détruit. Vous pouvez affaiblir une référence avec la fonction « weaken » exportée
par le module Scalar::Util.

Voici comment nous pouvons rendre le premier exemple plus sûr :

utiliser Scalar::Util 'affaiblissement';

mon $foo = {};
mon $bar = { foo => $foo };
$foo->{bar} = $bar;

affaiblir $foo->{bar};

La référence de $foo à $bar a été affaiblie. Lorsque la variable $bar sort de
portée, il sera récupéré par le ramasse-miettes. La prochaine fois que vous examinerez la valeur de
Touche "$foo->{bar}", ce sera "undef".

Cette action à distance peut être déroutante, vous devez donc être prudent avec votre utilisation de
affaiblir. Il faut affaiblir la référence dans la variable qui sera hors de portée. premier.
De cette façon, la variable à plus longue durée de vie contiendra la référence attendue jusqu'à ce qu'elle disparaisse.
de portée.

Symbolique
Nous avons dit que les références apparaissent si nécessaire si elles ne sont pas définies, mais nous
n'a pas dit ce qui se passe si une valeur utilisée comme référence est déjà définie, mais n'est pas a
Référence matérielle. Si vous l'utilisez comme référence, elle sera traitée comme une référence symbolique.
Autrement dit, la valeur du scalaire est considérée comme étant la prénom d'une variable, plutôt que d'un
lien direct vers une valeur (éventuellement) anonyme.

On s'attend souvent à ce que ça fonctionne comme ça. Et c'est le cas.

$name = "foo";
$$name = 1; # Définit $foo
${$name} = 2; # Définit $foo
${$name x 2} = 3; # Définit $foofoo
$name->[0] = 4; # Définit $foo[0]
@$name = (); # Efface @foo
&$name(); # Appelle &foo()
$pack = "CELA";
${"${pack}::$name"} = 5; # Définit $THAT::foo sans évaluation

C'est puissant et légèrement dangereux, dans la mesure où il est possible d'avoir l'intention (avec la plus grande prudence)
sincérité) d'utiliser une référence dure et d'utiliser accidentellement une référence symbolique à la place.
se protéger contre cela, vous pouvez dire

utiliser des « refs » stricts ;

et alors seules les références matérielles seront autorisées pour le reste du bloc englobant.
le bloc intérieur peut contredire cela avec

pas de "références" strictes ;

Seules les variables de package (globales, même si localisées) sont visibles pour les références symboliques.
Variables lexicales (déclarées avec ma()) ne sont pas dans une table de symboles et sont donc invisibles pour
ce mécanisme. Par exemple :

valeur locale $ = 10;
$ref = "valeur";
{
ma $valeur = 20;
imprimer $$ref;
}

Cela imprimera toujours 10, pas 20. N'oubliez pas que locale() affecte les variables du package, qui
sont tous « globaux » pour le package.

Pas si symbolique
Les crochets autour d'une référence symbolique peuvent simplement servir à isoler un identifiant ou une variable
nom du reste d'une expression, comme ils le font toujours dans une chaîne.
Par exemple,

$push = "pop sur ";
imprimer "${push}over";

a toujours signifié « pop on over », même si « push » est un mot réservé. C'est
généralisé pour fonctionner de la même manière sans les guillemets doubles, de sorte que

imprimer ${push} . "over";

et même

imprimer ${ push } . "over";

aura le même effet. Cette construction est pas considéré comme une référence symbolique
lorsque vous utilisez des références strictes :

utiliser des « refs » stricts ;
${ bareword }; # Ok, ça veut dire $bareword.
${ "bareword" }; # Erreur, référence symbolique.

De même, en raison de tous les indices qui sont effectués à l'aide de mots simples, la même règle
s'applique à tout mot nu utilisé pour l'indexation d'un hachage. Ainsi, au lieu d'écrire

$array{ "aaa" }{ "bbb" }{ "ccc" }

tu peux juste écrire

$array{ aaa }{ bbb }{ ccc }

et ne vous souciez pas de savoir si les indices sont des mots réservés. Dans le cas rare où vous
je souhaite faire quelque chose comme

$array{ shift }

vous pouvez forcer l'interprétation en tant que mot réservé en ajoutant tout ce qui le rend plus que
un mot simple :

$array{ shift() }
$array{ +shift }
$array{ shift @_ }

Le pragma « utiliser les avertissements » ou le -w le commutateur vous avertira s'il interprète un mot réservé
sous forme de chaîne. Cependant, l'avertissement concernant l'utilisation de mots en minuscules ne sera plus affiché, car
la chaîne est effectivement citée.

Pseudo-hachages : En utilisant an tableau as a hachage
Les pseudo-hachages ont été supprimés de Perl. Le pragma « fields » reste disponible.

Fonction Gabarits
Comme expliqué ci-dessus, une fonction anonyme avec accès aux variables lexicales visibles
Une fois cette fonction compilée, elle crée une fermeture. Elle conserve l'accès à ces variables.
même s'il n'est exécuté que plus tard, comme dans un gestionnaire de signaux ou un rappel Tk.

L'utilisation d'une fermeture comme modèle de fonction nous permet de générer de nombreuses fonctions qui agissent
De même. Supposons que vous souhaitiez des fonctions nommées d'après les couleurs qui génèrent la police HTML.
changements pour les différentes couleurs :

imprimer "Soyez ", rouge("prudent"), "avec ça ", vert("lumière");

Le manuel de formation rouge() et vert() Les fonctions seraient similaires. Pour les créer, nous allons assigner une fermeture
à un typeglob du nom de la fonction que nous essayons de construire.

@colors = qw(rouge bleu vert jaune orange violet violet);
pour mon $nom (@colors) {
pas de « références » strictes ; # autoriser la manipulation de la table des symboles
*$nom = *{uc $nom} = sous { " @_ " };
}

Désormais, toutes ces différentes fonctions semblent exister indépendamment. Vous pouvez appeler rouge(),
ROUGE(), bleu(), BLEU(), vert(), etc. Cette technique permet d'économiser à la fois du temps de compilation et de la mémoire
et est également moins sujet aux erreurs, car les vérifications de syntaxe ont lieu à la compilation.
Il est essentiel que toutes les variables de la sous-routine anonyme soient lexicales afin de créer un
Fermeture correcte. C'est la raison d'être de la variable d'itération de boucle « my ».

C'est l'un des seuls cas où donner un prototype à une fermeture a vraiment du sens. Si
vous vouliez imposer un contexte scalaire sur les arguments de ces fonctions (probablement pas un
(idée judicieuse pour cet exemple particulier), vous auriez pu l'écrire de cette façon à la place :

*$name = sub($) { " $_[0] " };

Cependant, comme la vérification du prototype se produit au moment de la compilation, l'affectation ci-dessus se produit
trop tard pour être d'une grande utilité. Vous pourriez résoudre ce problème en mettant toute la boucle de
affectations dans un bloc BEGIN, forçant son exécution pendant la compilation.

Accès aux lexiques qui changent au fil du temps, comme ceux de la boucle « for » ci-dessus, en gros
alias vers des éléments des portées lexicales environnantes - fonctionne uniquement avec des sous-ensembles anonymes,
pas avec des sous-routines nommées. En général, les sous-routines nommées ne s'imbriquent pas correctement et
ne doit être déclaré que dans la portée du package principal.

C'est parce que les sous-routines nommées sont créées au moment de la compilation, donc leurs variables lexicales
sont assignés aux lexiques parents dès la première exécution du bloc parent. Si un
la portée parent est saisie une deuxième fois, ses lexicaux sont à nouveau créés, tandis que la portée imbriquée
les sous-titres font toujours référence aux anciens.

Les sous-routines anonymes parviennent à capturer chaque fois que vous exécutez l'opérateur « sub », car elles sont
créées à la volée. Si vous êtes habitué à utiliser des sous-routines imbriquées dans d'autres programmes,
langages avec leurs propres variables privées, vous devrez travailler un peu dessus en Perl.
Le codage intuitif de ce type de chose entraîne des avertissements mystérieux du type « ne restera pas
« Partagé » pour les raisons expliquées ci-dessus. Par exemple, ceci ne fonctionnera pas :

sous-extérieur {
mon $x = $_[0] + 35;
sous-intérieur {retour $x * 19} # FAUX
retourner $x + inner();
}

Une solution de contournement est la suivante :

sous-extérieur {
mon $x = $_[0] + 35;
local *inner = sub { return $x * 19 };
retourner $x + inner();
}

Maintenant intérieur() ne peut être appelé que de l'intérieur extérieur(), en raison des missions temporaires
de la sous-routine anonyme. Mais lorsqu'elle le fait, elle a un accès normal au lexique
variable $x de la portée de extérieur() au moment où outer est invoqué.

Cela a l’effet intéressant de créer une fonction locale à une autre fonction,
quelque chose qui n'est normalement pas pris en charge dans Perl.

ATTENTION


Vous ne pouvez pas (utilement) utiliser une référence comme clé d'un hachage. Elle sera convertie en
chaîne:

$x{ \$a } = $a;

Si vous essayez de déréférencer la clé, cela n'effectuera pas de déréférencement dur et vous ne
accomplir ce que vous tentez. Vous pourriez vouloir faire quelque chose de plus proche

$r = \@a;
$x{ $r } = $r;

Et puis au moins tu peux utiliser le valeurs (), qui seront de véritables arbitres, au lieu des
clés(), ce qui ne le sera pas.

Le module standard Tie::RefHash fournit une solution de contournement pratique à ce problème.

Postfix Déréférencement Syntaxe


Depuis la version 5.20.0, une syntaxe postfixée permettant d'utiliser des références est disponible. Son comportement est le suivant :
décrit dans « Utilisation des références », mais au lieu d'un sigil préfixé, un sigil postfixé-et-
l'étoile est utilisée.

Par exemple :

$r = \@a;
@b = $r->@*; # équivalent à @$r ou @{ $r }

$r = [ 1, [ 2, 3 ], 4 ];
$r->[1]->@*; # équivalent à @{ $r->[1] }

Cette syntaxe doit être activée avec la fonctionnalité « use feature 'postderef' ». Elle est expérimentale et
avertir par défaut à moins que « aucun avertissement 'experimental::postderef' » ne soit en vigueur.

La déréférencement de postfixe devrait fonctionner dans toutes les circonstances où la déréférencement de bloc (circonfixe)
a fonctionné et devrait être entièrement équivalent. Cette syntaxe permet d'écrire des déréférencements
et se lit entièrement de gauche à droite. Les équivalences suivantes sont définies :

$sref->$*; # identique à ${ $sref }
$aref->@*; # identique à @{ $aref }
$aref->$#* ; # identique à $#{ $aref }
$href->%* ; # identique à %{ $href }
$cref->&*; # identique à &{ $cref }
$gref->** ; # identique à *{ $gref }

Notez en particulier que "$cref->&*" est pas équivalent à "$cref->()", et peut servir à différents
fins pratiques.

Les éléments Glob peuvent être extraits via la fonctionnalité de déréférencement postfixe :

$gref->*{SCALAIRE}; # identique à *{ $gref }{SCALAIRE}

Déréférencement de tableaux et de scalaires Postfix Vous pouvez être utilisé dans l'interpolation de chaînes (guillemets doubles
ou l'opérateur « qq »), mais uniquement si la fonctionnalité supplémentaire « postderef_qq » est activée.

Postfix Références Slicing
Les tranches de valeur des tableaux et des hachages peuvent également être prises avec une notation de déréférencement postfixée,
avec les équivalences suivantes :

$aref->@[ ... ]; # identique à @$aref[ ... ]
$href->@{ ... }; # identique à @$href{ ... }

Découpage des paires clé/valeur de Postfix, ajouté dans la version 5.20.0 et documenté dans le hachage clé/valeur
La section Slices de perldata se comporte également comme prévu :

$aref->%[ ... ]; # identique à %$aref[ ... ]
$href->%{ ... } ; # identique à %$href{ ... }

Comme pour le tableau postfix, déréférencement de tranche de valeur postfix Vous pouvez être utilisé dans l'interpolation
chaînes (guillemets doubles ou opérateur « qq »), mais uniquement si le « postderef_qq » supplémentaire
fonction est activée.

Attribution à Références


À partir de la version 5.22.0, l'opérateur de référencement peut être assigné à. Il effectue une
opération d'aliasing, de sorte que le nom de variable référencé sur le côté gauche devienne un
alias pour la chose référencée sur le côté droit :

\$a = \$b; # $a et $b pointent maintenant vers le même scalaire
\&foo = \&bar; # foo() signifie maintenant bar()

Cette syntaxe doit être activée avec la fonctionnalité « utiliser le refaliasing ». Elle est expérimentale.
avertira par défaut à moins que « aucun avertissement 'experimental::refaliasing' » ne soit en vigueur.

Ces formes peuvent être assignées et faire en sorte que le côté droit soit évalué en scalaire
le contexte:

\$scalaire
\@tableau
\%hacher
\&sous
\mon $scalaire
\mon @array
\mon %hash
\state $scalar # ou @array, etc.
\notre $scalaire # etc.
\local $scalaire # etc.
\local notre $scalaire # etc.
\$some_array[$index]
\$some_hash{$key}
\local $some_array[$index]
\local $some_hash{$key}
condition ? \$ceci : \$cela[0] # etc.

Les opérations de découpage et les parenthèses entraînent l'évaluation du côté droit dans la liste
le contexte:

\@array[5..7]
(\@array[5..7])
\(@array[5..7])
\@hash{'foo','bar'}
(\@hash{'foo','bar'})
\(@hash{'foo','bar'})
(\$scalaire)
\($scalaire)
\(mon $scalaire)
\my($scalaire)
(\@tableau)
(\%hacher)
(\&sous)
\(&sous)
\($foo, @bar, %baz)
(\$foo, \@bar, \%baz)

Chaque élément du côté droit doit être une référence à une donnée du bon type.
Les parenthèses entourant immédiatement un tableau (et éventuellement aussi
"mon"/"état"/"notre"/"local") fera de chaque élément du tableau un alias du
scalaire correspondant référencé sur le côté droit :

\(@a) = \(@b); # @a et @b ont maintenant les mêmes éléments
\my(@a) = \(@b); # de même
\(mon @a) = \(@b); # de même
pousser @a, 3; # mais maintenant @a a un élément supplémentaire qui manque à @b
\(@a) = (\$a, \$b, \$c); # @a contient maintenant $a, $b et $c

Combiner cette forme avec « local » et mettre des parenthèses immédiatement autour d'un hachage est
interdit (car ce qu'ils doivent faire n'est pas clair) :

\local(@array) = foo(); # FAUX
\(%hash) = bar(); # FAUX

L'affectation à des références et à des non-références peut être combinée dans des listes et des conditions.
expressions ternaires, à condition que les valeurs du côté droit soient du bon type pour
chaque élément à gauche, bien que cela puisse donner lieu à un code obscurci :

(mon $tom, \ma $bite, \mon @harry) = (\1, \2, [1..3]);
# $tom est maintenant \1
# $dick est maintenant 2 (lecture seule)
# @harry est (1,2,3)

mon $type = ref $thingy;
($type ? $type == 'ARRAY' ? \@foo : \$bar : $baz) = $thingy;

La boucle « foreach » peut également prendre un constructeur de référence pour sa variable de boucle, bien que le
la syntaxe est limitée à l'une des suivantes, avec un « mon », « état » ou « notre » facultatif après
la barre oblique inverse :

\$s
\@un
\%h
\&c

Les parenthèses ne sont pas autorisées. Cette fonctionnalité est particulièrement utile pour les tableaux de tableaux.
ou tableaux de hachages :

foreach \my @a (@array_of_arrays) {
frobnicate($a[0], $a[-1]);
}

foreach \my %h (@array_of_hashes) {
$h{gelastic}++ si $h{type} == 'drôle';
}

CAVEAT: L'aliasing ne fonctionne pas correctement avec les fermetures. Si vous essayez d'aliaser des éléments lexicaux,
variables d'une sous-routine interne ou « eval », l'aliasing ne sera visible qu'à l'intérieur
cette sous-routine interne, et n'affectera pas la sous-routine externe où les variables sont déclarées.
Ce comportement bizarre est susceptible de changer.

Utiliser perlref en ligne avec les services onworks.net


Serveurs et postes de travail gratuits

Télécharger des applications Windows et Linux

Commandes Linux

Ad




×
Publicité
❤ ️Achetez, réservez ou achetez ici — gratuitement, contribue à maintenir la gratuité des services.