9
votes

À Perl, y a-t-il une différence entre l'aliasing direct globe et l'aliasing via la cachette?

en Perl, y a-t-il une différence entre les deux constructions suivantes: xxx

et xxx

Ils semblent avoir la même chose Fonction (aliasant tous les emplacements dans * Main :: FOO à ceux définis dans * Main :: Bar ), mais je me demande simplement si cette équivalence tient toujours. < / p>


6 commentaires

Je suis curieux ce qui a amené ça. :)


Le premier provoque une erreur lorsque des «sous-marins» stricts ou stricts sont activés, ce dernier est autorisé.


J'écris une boucle à alias quelques noms de méthodes ensemble et j'ai commencé à se demander pourquoi j'écris toujours {pas strict 'REFS'; * {'Certains :: pkg'. $ nouveau} = * {'Certains :: pkg'. $ old} quand $ € Quelque :: pkg :: {$ nouveau} = :: {$ old} fonctionnerait aussi bien. Intuitivement, ils semblent les mêmes, mais des choses comme des cravates / des surcharges / autres magiques pourraient avoir des conséquences «intéressantes» s'ils gèrent la copie différente, soit comme un bug ou un comportement prévu.


@MKV => L'exemple de ma question fonctionne bien sous strict. Un identifiant entièrement qualifié est exempté des strictures. L'exemple de mon commentaire ci-dessus nécessite de désactiver des références strictes en raison de la déréférence symbolique, mais n'a rien à voir avec le Glob même.


Ouais, pense. Je pensais la différence entre * foo = * bar et $ :: {foo} = $ :: {bar} lorsque le paquet actuel est "Main".


@MKV => Cet exemple est bien sous strict aussi, je ne suis pas sûr de ce que vous obtenez.


4 Réponses :


3
votes

Le script suivant: xxx

sorties: xxx

donc si * main :: foo = * main :: bar; ne fait pas la même chose que $ MAIN :: {FOO} = $ MAIN :: {bar}; , je suis à perte de savoir comment détecter un Différence pratique. ;) Cependant, d'une perspective de syntaxe, il peut exister des situations où il est plus facile d'utiliser une méthode par rapport à une autre. ... Les avertissements habituels sur la chahute dans la table des symboles s'appliquent toujours.


2 commentaires

Je suppose que toute différence (s'il y en a une) serait dans une magie ésotérique ou un algorithme de mise en cache excessive. Syntaxiquement, il existe définitivement des différences, le code de l'affectation globale couplée à pas strict 'REFS' dans une routine Importation est un peu plus court (et plus rapide) que de prendre manuellement l'appelant À part et marcher sur le niveau de la table des symboles par niveau, ce qui me conduit à préférer la syntaxe globe, mais lorsque vous écrivez à un nom pleinement qualifié connu à l'avance (ou en traitement déjà une réserve pour une autre raison), la différence syntaxique est un peu trouble, D'où la question :)


En regardant sous la capuche, c'est une diversion amusante. Je pense qu'il y a des situations où la bonne vieille notation Glob est la plus claire, alors qu'il existe d'autres situations où l'espace $ de noms :: {Key} Notation est plus clair. Quel que soit l'un plus clair pour un besoin particulier, c'est la façon de le faire. :) Bien sûr, si une personne peut trouver une alternative à la pataugeation à travers la table des symboles, il y a beaucoup de raisons pour éviter l'une ou l'autre approche par conception.



3
votes

accéder à la cachette comme $ A :: {foo} = $ obj code> vous permet de placer quelque chose sur la table des symboles tandis que * A :: foo = $ obj code> $ obj code> sur la fente attendue du typeglob selon $ obj code> type.

Par exemple: p>

  DB<1> $ST::{foo} = [1,2,3]

  DB<2> *ST::bar = [1,2,3]

  DB<3> x @ST::foo
Cannot convert a reference to ARRAY to typeglob at (eval 7)[/usr/local/perl/blead-debug/lib/5.15.0/perl5db.pl:646] line 2.
 at (eval 7)[/usr/local/perl/blead-debug/lib/5.15.0/perl5db.pl:646] line 2
    eval '($@, $!, $^E, $,, $/, $\\, $^W) = @saved;package main; $^D = $^D | $DB::db_stop;
  @ST::foo;

;' called at /usr/local/perl/blead-debug/lib/5.15.0/perl5db.pl line 646
    DB::eval called at /usr/local/perl/blead-debug/lib/5.15.0/perl5db.pl line 3442
    DB::DB called at -e line 1
  DB<4> x @ST::bar
0  1
1  2
2  3
  DB<5> x \%ST::
0  HASH(0x1d55810)
   'bar' => *ST::bar
   'foo' => ARRAY(0x1923e30)
      0  1
      1  2
      2  3


0 commentaires

9
votes

Peut-être pas le genre de différence que vous recherchiez, mais il y a deux grandes différences entre * Main :: FOO et $ principale :: {foo} ; Le premier regarde le globe dans la cachette au moment de la compilation, la créant si nécessaire, tandis que cette dernière recherche le Glob dans la cachette au moment de l'exécution et ne le créera pas.

Ceci peut faire une différence sur quoi que ce soit d'autre piquer dans la cachette, et cela peut certainement affecter si vous obtenez un utilisé une fois AVERTISSEMENT.


2 commentaires

Pour les gens comme moi qui ne sont pas dans Perl Esoterics: Stashes et Globs : "<< I> une cachette est un hachage contenant tous les différents objets contenus dans un colis. Chaque clé de la cachette est un nom de symbole (partagé par tous les différents types d'objets ayant le même nom) et chaque valeur dans La table de hachage est une GV (valeur globale). Ce GV est à son tour contient des références aux différents objets de ce nom "... Le tour perl ne finit jamais!


@Davidtonhofer surtout depuis que ce n'est pas assez précis; Dans certains cas, la cachette peut avoir des valeurs qui ne sont pas GVS.



0
votes

Voir aussi "scalaires vs globs (* {} ne doit pas renvoyer de fausses globs)"

https://github.com/perl/perl5/issues/10625


1 commentaires

Bien que ce lien puisse répondre à la question, il est préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien pour référence. Les réponses de liaison seules peuvent devenir invalides si la page liée change