Quel est le moyen le plus efficace d'accomplir ci-dessous? (Je sais qu'ils accomplissent la même chose, mais comment la plupart des gens feraient-ils cela entre les trois, et pourquoi em>?) fichier A.pl h3>
Fichier B.PL H3>
my %hash = %{build_hash()};
# Do stuff with hash using $hash{$key}
# It is better, because now we don't have to dereference our hashref each time using ->?
sub build_hash
{
# Build some hash
my %hash = ();
my @k = qw(hi bi no th xc ul 8e r);
for ( @k )
{
$hash{$k} = 1;
}
return \%hash;
}
8 Réponses :
Je retournerais la référence pour enregistrer le temps de traitement de l'aplatissement du hachage dans une liste de scalaires, construire le nouveau hachage et (éventuellement) déchets collectant le hachage local dans le sous-programme. p>
Ce que vous cherchez est un tranche de hachage em>: L'opérateur Voir Perldoc Perldsc et Perldoc Perlrefut A > Pour les tutoriels sur les structures de données et les références (les deux incontournables des débutants et des experts). Les tranches de hachage elles-mêmes sont mentionnées dans Perldoc Perldata . P> En ce qui concerne le retour d'un hachage À partir d'une fonction, nous devriez normalement retourner le hachage lui-même, pas une référence. Vous pouvez utiliser une référence si le hachage est énorme em> et que la mémoire ou le temps est une préoccupation, mais cela ne devrait pas être votre préoccupation de préoccupation - obtenir le code de travail est. P> retour Les valeurs des fonctions sont toujours des listes (où le retour d'un scalaire est essentiellement une liste d'un élément). Les hachages sont des listes de Perl: vous pouvez attribuer une autre à l'autre interchangeable (en supposant que la liste a un nombre pair d'éléments et il n'y a pas de collisions clés qui entraîneraient des valeurs perdues pendant la conversion): P> x code> est décrit à Perldoc Perlop . P>
$VAR1 = [
'key1',
'value1',
'key2',
'value2'
];
$VAR1 = {
'key2' => 'value2',
'key1' => 'value1'
};
Dans le codeBase, je travaille actuellement avec cela, ce serait une fonction simple appelée hashof code> exporté par le projetNamespace :: DataManip Fonction et approximativement implémenté comme
Sub Hashof {Retourte {$ _ => 1} @_;} code> (avec un prototype de sucre et similaires). Notre
hash_slice_of ($ hashref, @list) code> d'autre part chaque paire de la valeur de clé qui
existe code> en $ hashref où la clé est également dans @List. En tant que fonction de manipulation de hachage, ils renvoient tous les hachages (listes de taille même) afin que les valeurs de retour soient plus faciles à utiliser et à passer les unes aux autres.
Prenez un soin: Pour la même raison, la construction d'un hachage, la façon dont vous décrivez est aussi simple que: p> ma règle de base personnelle est d'éviter les références à moins que je ne fais pas besoin d'eux (par exemple, des structures imbriquées ou lorsque vous avez vraiment besoin de transmettre une référence à la même chose em>). p> EDIT: (Je ne peux pas cliquer sur "Ajouter un commentaire" link plus ?! Utilisation de la souris ici ...)
J'y ai pensé un peu et je pense que passer autour de Hash Refs est probablement meilleur après tout, grâce à la façon dont nous utilisons un hash. Le paragraphe ci-dessus est toujours tenu pour le tableau Refs. P> Merci pour vos commentaires Schwern et éther. P> P> a.pl code> renvoie une liste em> avec un nombre pair d'éléments, pas un hash. Lorsque vous attribuez ensuite une telle liste à une variable de hachage, le hachage sera construit avec les éléments aux indices même en tant que touches et éléments des indices impairs en tant que valeurs. [EDIT: C'était comme ça que j'ai toujours vu la matière, mais
Sub {...% hachage} code> se comporte un peu différemment de
sous {... @List} code>. ]
+1 à l'utilisation de la carte pour créer un hachage d'une liste, -1 à l'idée d'éviter les références.
a.pl code> et
c.pl code> nécessite une copie du hachage à prendre (et le hachage interne à la fonction est marqué comme mémoire libre).
b.pl code>, d'autre part, construit le hachage une seule fois et nécessite peu de mémoire supplémentaire pour renvoyer une référence sur laquelle vous pouvez utiliser. Ainsi,
b.pl code> est plus susceptible d'être la forme la plus efficace des trois, à la fois dans l'espace et dans le temps. P>
Je préfère retourner un hachage Ref pour deux raisons. Un, il utilise un peu moins de mémoire car il n'y a pas de copie. Deux, il vous permet de le faire si vous avez juste besoin d'un morceau de hachage. Apprenez à aimer les références de hachage, vous allez les voir beaucoup une fois que vous avez commencé à utiliser des objets. p> p>
Voulez-vous des œufs avec ça? (une référence de hachage implicite :)
Je vais aller contre le grain et ce que tout le monde dit, et disons que je préfère que mes données sont revenues en tant que hachage (bien, en tant que liste de taille même susceptible d'être interprétée comme un hachage ). Je travaille dans un environnement où nous avons tendance à faire des choses comme l'extrait de code suivant, et il est beaucoup plus facile de combiner et de trier et de trancher et de couper des morts lorsque vous n'avez pas à Dréérence toutes les autres lignes. (Il est également agréable de savoir que quelqu'un ne peut pas endommager votre hashref parce que vous avez passé la valeur tout en valeur. EDIT: STRUT> Sauf si vous avez des références à d'autres objets / hachages / tableaux dans les valeurs de hachage. , alors vous êtes en difficulté quand même). my %filtered_config_slice =
hashgrep { $a !~ /^apparent_/ && defined $b } (
map { $_->build_config_slice(%some_params, some_other => 'param') }
($self->partial_config_strategies, $other_config_strategy)
);
Le problème est l'utilisation de la mémoire, pas nécessairement la vitesse. Lorsque vous êtes cavalier avec une utilisation de la mémoire, l'empreinte de votre application a tendance à exploser. Voir la réponse de Schwern.
Pourquoi ne pas renvoyer les deux? Le contexte est une fonctionnalité très puissante de Perl pour permettre à vos fonctions de "faire ce que tu veux dire". Souvent, la décision est une meilleure valeur de rendement dépend de la manière dont le code d'appel prévoit utiliser la valeur, ce qui est exactement pourquoi Perl a le WANTLARRAY code>.
sub build_hash {
my %hash;
@hash{@keys} = (1) x @keys;
wantarray ? %hash : \%hash
}
my %hash = build_hash; # list context, a list of (key => value) pairs
my $href = build_hash; # scalar context, a hash reference
mon ($ href) = build_hash (); # whoops code> un peu trop d'aide pour pas assez de victoire.
@Schwern => Si une personne travaillant dans Perl ne peut pas reconnaître que la LValue est imposante sur le contexte de la liste sur la mission, ils ne vont pas aller très loin. Plutôt que de cacher ces caractéristiques des personnes, ceux qui les comprennent devraient aider les autres à les utiliser correctement.
@Eric il ne s'agit pas de ne pas comprendre les contextes. Son que vous vous attendiez à ce que Build_Hash () renvoie quelque chose de différent dans le contexte de la liste. Ne croyez pas que les études de l'utilisateur et se souvient pour toujours de la documentation de chaque fonction. Son composé dans ce mon ($ foo) code> et
mon $ foo code> est assez facile à échanger avec désinvolture. Aussi
fonction (build_hash ()) code>. Oups. Des bugs subtils manqués facilement. Enfin, le réaménagement d'un hachage n'a pas l'utilité du retour d'une liste. Un hachage doit être coincé dans une variable pour être utile. Le retour d'une liste peut être utilisé implicitement, style LISP. Donc, je questionne la valeur.
En ce qui concerne le retour d'un hachage d'un fonction, normalement, vous devriez revenir le hachage lui-même, pas une référence. Tu pourrait utiliser une référence si le hachage est énorme et la mémoire ou le temps est une préoccupation, Mais cela ne devrait pas être votre premier souci - Obtenir le code du code est. P> blockQuote>
Je vais devoir être en désaccord avec éther ici. Il y avait un moment où j'ai pris cette position, mais je me suis rapidement retrouvé descendre dans un enfer de devoir me rappeler que
Sub code> S est retourné hachage et qui a renvoyé HashRefs, qui était un obstacle assez grave pour simplement obtenir le code travail. Il est important de normaliser sur toujours em> renvoyer un hachage / tableau ou toujours em> renvoyer un hashref / arrayref, à moins que vous ne vouliez pas vous trébucher constamment sur vous-même. P>
Quant auxquels standardiser, je vois plusieurs avantages d'aller avec des références: p>
Lorsque vous retournez un hachage ou une matrice, ce que vous retournez réellement est une liste contenant une copie aplatie du hachage / matrice d'origine. Tout comme passer dans les paramètres de hachage / tableau vers un
sous code>, cela a l'inconvénient que vous ne pouvez envoyer qu'une liste à la fois. Accordé, vous n'avez pas souvent besoin de retourner plusieurs listes de valeurs, mais cela se produit, alors pourquoi choisir de standardiser de faire des choses de manière à l'exclure? P> LI>
Les performances (généralement négligeables) et les avantages de la mémoire du renvoi d'un scalaire unique plutôt que d'une partie de données potentiellement beaucoup plus importante. P> li>
Il maintient la cohérence avec le code de l'OO, qui transmet fréquemment des objets (c'est-à-dire des références bénies) d'avant en avant. p> li>
Si, pour une raison quelconque, il est important que vous ayez une copie fraîche du hachage / matrice plutôt que d'une référence à l'original, le code d'appel peut facilement en faire un, comme le démontrant l'OP dans
C .pl code>. Si vous retournez une copie du hachage, il n'ya aucun moyen que l'appelant puisse le tourner en une référence à l'original. (Dans les cas où cela est avantageux, la fonction peut effectuer une copie et renvoyer une référence à la copie, protégeant ainsi l'original tout en évitant également " ce em> renvoie hachage, que em> Retourne Hashrefs "Hell j'ai mentionné plus tôt.) P> Li>
Comme Schwern a mentionné, c'est vraiment agréable de pouvoir faire
mon $ foo = $ obj-> quelque_data -> {key} p> li> ul>
Le seul avantage que je puisse voir à Toujours em> Retourner les hachages / matrices est qu'il est plus facile pour ceux qui ne comprennent pas les références ou ne sont pas à l'aise de travailler avec eux. Étant donné que le confort des références prend des semaines ou des mois à développer, suivis de années ou de décennies de travailler avec elles couramment, je ne considère pas cela un avantage significatif. P>
+1, le maintien de la cohérence est un bon point. Cependant, étant donné que j'utilise des tableaux plus souvent en tant que matrices que j'utilise des hachage comme hatupes, et comme il y aurait beaucoup plus de déséroférences / copie de sécurité pour les rayons REFS, je pense qu'ils devraient être traités différemment.
Voir la question associée à la question perl retourne des fonctions, meilleures pratiques i > (il apparaît dans la liste associée à droite de cette page ...).
@DaoToad: Ne vous inquiétez pas sur le retour du contexte scalaire d'une fonction qui n'a aucun sens à appeler dans le contexte scalaire
Nous couvrons beaucoup de cela dans Perl intermédiaire ( Oreilly.com/catalog/9780596102067 ).