Question

J'ai une fonction qui prend une variable et un tableau associatif, mais je n'arrive pas à les faire passer correctement. Je pense que cela a quelque chose à voir avec les déclarations de fonction, mais je ne peux pas comprendre comment elles fonctionnent en Perl. Y at-il une bonne référence pour cela et comment puis-je accomplir ce dont j'ai besoin?

J'ajouterais qu'il doit être transmis par référence.

sub PrintAA
{
    my $test = shift;
    my %aa   = shift;
    print $test . "\n";
    foreach (keys %aa)
    {
        print 

J'ai une fonction qui prend une variable et un tableau associatif, mais je n'arrive pas à les faire passer correctement. Je pense que cela a quelque chose à voir avec les déclarations de fonction, mais je ne peux pas comprendre comment elles fonctionnent en Perl. Y at-il une bonne référence pour cela et comment puis-je accomplir ce dont j'ai besoin?

J'ajouterais qu'il doit être transmis par référence.

<*> . " : " . $aa{

J'ai une fonction qui prend une variable et un tableau associatif, mais je n'arrive pas à les faire passer correctement. Je pense que cela a quelque chose à voir avec les déclarations de fonction, mais je ne peux pas comprendre comment elles fonctionnent en Perl. Y at-il une bonne référence pour cela et comment puis-je accomplir ce dont j'ai besoin?

J'ajouterais qu'il doit être transmis par référence.

<*>} . "\n"; $aa{

J'ai une fonction qui prend une variable et un tableau associatif, mais je n'arrive pas à les faire passer correctement. Je pense que cela a quelque chose à voir avec les déclarations de fonction, mais je ne peux pas comprendre comment elles fonctionnent en Perl. Y at-il une bonne référence pour cela et comment puis-je accomplir ce dont j'ai besoin?

J'ajouterais qu'il doit être transmis par référence.

<*>} = $aa{

J'ai une fonction qui prend une variable et un tableau associatif, mais je n'arrive pas à les faire passer correctement. Je pense que cela a quelque chose à voir avec les déclarations de fonction, mais je ne peux pas comprendre comment elles fonctionnent en Perl. Y at-il une bonne référence pour cela et comment puis-je accomplir ce dont j'ai besoin?

J'ajouterais qu'il doit être transmis par référence.

<*>} . "+"; } }
Était-ce utile?

La solution

Passez la référence au lieu du hachage lui-même. Comme dans

PrintAA("abc", \%fooHash);

sub PrintAA
{
  my $test = shift;
  my $aaRef = shift;

  print $test, "\n";
  foreach (keys %{$aaRef})
  {
    print 

Passez la référence au lieu du hachage lui-même. Comme dans

<*>

Voir aussi perlfaq7: Comment puis-je transmettre / retourner une {Fonction, un FileHandle, un Array, une Méthode, un Regex}?

, " : ", $aaRef->{

Passez la référence au lieu du hachage lui-même. Comme dans

<*>

Voir aussi perlfaq7: Comment puis-je transmettre / retourner une {Fonction, un FileHandle, un Array, une Méthode, un Regex}?

}, "\n"; } }

Voir aussi perlfaq7: Comment puis-je transmettre / retourner une {Fonction, un FileHandle, un Array, une Méthode, un Regex}?

Autres conseils

Ce code fonctionne:

#!/bin/perl -w

use strict;

sub PrintAA
{
    my($test, %aa) = @_;
    print $test . "\n";
    foreach (keys %aa)
    {
        print 

Ce code fonctionne:

my $test = shift;
my(%aa) = @_;

Le point clé est l’utilisation du contexte de tableau dans l’instruction my () de la fonction.

  

Que fait réellement le commerce de contexte de groupe?

En résumé, cela fonctionne correctement.

Cela signifie que la première valeur du tableau d'arguments @_ est affectée à $ test et que les éléments restants sont affectés à la table de hachage % aa . Comme je l’appelais, le @_ contient un nombre impair d’éléments. Ainsi, dès que le premier élément est affecté à $ test , il existe un nombre pair de éléments disponibles à affecter à % aa , le premier élément de chaque paire étant la clé ('aaa', 'bbb', 'ccc' dans mon exemple) et le second étant la valeur correspondante.

Il serait possible de remplacer % aa par @aa , auquel cas le tableau aurait 6 éléments. Il serait également possible de remplacer % aa par $ aa , et dans ce cas, la variable $ aa contiendrait la valeur 'aaa' , et les valeurs restantes dans @_ seraient ignorées par l'affectation.

Si vous omettez les parenthèses autour de la liste de variables, Perl refuse de compiler le code. Une des réponses alternatives montrait la notation:

Reference found where even-sized list expected at xx.pl line 18.
...
Use of uninitialized value in concatenation (.) or string at xx.pl line 13.

Ceci est à peu près équivalent à ce que j'ai écrit; la différence est qu'après les deux instructions my , @_ ne contient que 6 éléments dans cette variante, alors que dans la version unique my , contient 7 éléments.

Il y a certainement d'autres questions dans SO sur le contexte du tableau.

  

En fait, je ne posais pas de questions sur le my ($ test,% aa) = @_; à propos de my (% hash) = ('aaa' = > ; 1, 'bbb' = > 'balles', 'ccc' = > \ & amp;; PrintAA); versus mon% hash = {'aaa' = > 1, ...};

La différence est que la notation {...} génère un hacha ref et que la notation (...) génère une liste, qui mappe sur un hachage (par opposition à un hacha ref). De même, [...] génère un tableau ref et non un tableau.

En effet, changez le code "principal" pour qu'il se lise: my (% hash) = {...}; et vous obtenez une erreur d'exécution (mais pas de compilation) - traitez les numéros de ligne avec prudence, car j'ai ajouté des codages alternatifs à mon fichier:

<*> . " : " . $aa{

Ce code fonctionne:

<*>

Le point clé est l’utilisation du contexte de tableau dans l’instruction my () de la fonction.

  

Que fait réellement le commerce de contexte de groupe?

En résumé, cela fonctionne correctement.

Cela signifie que la première valeur du tableau d'arguments @_ est affectée à $ test et que les éléments restants sont affectés à la table de hachage % aa . Comme je l’appelais, le @_ contient un nombre impair d’éléments. Ainsi, dès que le premier élément est affecté à $ test , il existe un nombre pair de éléments disponibles à affecter à % aa , le premier élément de chaque paire étant la clé ('aaa', 'bbb', 'ccc' dans mon exemple) et le second étant la valeur correspondante.

Il serait possible de remplacer % aa par @aa , auquel cas le tableau aurait 6 éléments. Il serait également possible de remplacer % aa par $ aa , et dans ce cas, la variable $ aa contiendrait la valeur 'aaa' , et les valeurs restantes dans @_ seraient ignorées par l'affectation.

Si vous omettez les parenthèses autour de la liste de variables, Perl refuse de compiler le code. Une des réponses alternatives montrait la notation:

<*>

Ceci est à peu près équivalent à ce que j'ai écrit; la différence est qu'après les deux instructions my , @_ ne contient que 6 éléments dans cette variante, alors que dans la version unique my , contient 7 éléments.

Il y a certainement d'autres questions dans SO sur le contexte du tableau.

  

En fait, je ne posais pas de questions sur le my ($ test,% aa) = @_; à propos de my (% hash) = ('aaa' = > ; 1, 'bbb' = > 'balles', 'ccc' = > \ & amp;; PrintAA); versus mon% hash = {'aaa' = > 1, ...};

La différence est que la notation {...} génère un hacha ref et que la notation (...) génère une liste, qui mappe sur un hachage (par opposition à un hacha ref). De même, [...] génère un tableau ref et non un tableau.

En effet, changez le code "principal" pour qu'il se lise: my (% hash) = {...}; et vous obtenez une erreur d'exécution (mais pas de compilation) - traitez les numéros de ligne avec prudence, car j'ai ajouté des codages alternatifs à mon fichier:

<*>} . "\n"; } } my(%hash) = ( 'aaa' => 1, 'bbb' => 'balls', 'ccc' => \&PrintAA ); PrintAA("test", %hash);

Le point clé est l’utilisation du contexte de tableau dans l’instruction my () de la fonction.

  

Que fait réellement le commerce de contexte de groupe?

En résumé, cela fonctionne correctement.

Cela signifie que la première valeur du tableau d'arguments @_ est affectée à $ test et que les éléments restants sont affectés à la table de hachage % aa . Comme je l’appelais, le @_ contient un nombre impair d’éléments. Ainsi, dès que le premier élément est affecté à $ test , il existe un nombre pair de éléments disponibles à affecter à % aa , le premier élément de chaque paire étant la clé ('aaa', 'bbb', 'ccc' dans mon exemple) et le second étant la valeur correspondante.

Il serait possible de remplacer % aa par @aa , auquel cas le tableau aurait 6 éléments. Il serait également possible de remplacer % aa par $ aa , et dans ce cas, la variable $ aa contiendrait la valeur 'aaa' , et les valeurs restantes dans @_ seraient ignorées par l'affectation.

Si vous omettez les parenthèses autour de la liste de variables, Perl refuse de compiler le code. Une des réponses alternatives montrait la notation:

<*>

Ceci est à peu près équivalent à ce que j'ai écrit; la différence est qu'après les deux instructions my , @_ ne contient que 6 éléments dans cette variante, alors que dans la version unique my , contient 7 éléments.

Il y a certainement d'autres questions dans SO sur le contexte du tableau.

  

En fait, je ne posais pas de questions sur le my ($ test,% aa) = @_; à propos de my (% hash) = ('aaa' = > ; 1, 'bbb' = > 'balles', 'ccc' = > \ & amp;; PrintAA); versus mon% hash = {'aaa' = > 1, ...};

La différence est que la notation {...} génère un hacha ref et que la notation (...) génère une liste, qui mappe sur un hachage (par opposition à un hacha ref). De même, [...] génère un tableau ref et non un tableau.

En effet, changez le code "principal" pour qu'il se lise: my (% hash) = {...}; et vous obtenez une erreur d'exécution (mais pas de compilation) - traitez les numéros de ligne avec prudence, car j'ai ajouté des codages alternatifs à mon fichier:

<*>

Alternativement:

sub PrintAA
{
    my $test       = shift;
    my %aa         = @_;
        print $test . "\n";
        foreach (keys %aa)
        {
                print 

Alternativement:

<*>

Ce qui vous manque fondamentalement, c'est qu'un tableau associatif n'est pas un argument unique (bien qu'une référence à un tableau associatif soit, comme dans la réponse de Paul Tomblin).

. " : " . $aa{

Alternativement:

<*>

Ce qui vous manque fondamentalement, c'est qu'un tableau associatif n'est pas un argument unique (bien qu'une référence à un tableau associatif soit, comme dans la réponse de Paul Tomblin).

} . "\n"; $aa{

Alternativement:

<*>

Ce qui vous manque fondamentalement, c'est qu'un tableau associatif n'est pas un argument unique (bien qu'une référence à un tableau associatif soit, comme dans la réponse de Paul Tomblin).

} = $aa{

Alternativement:

<*>

Ce qui vous manque fondamentalement, c'est qu'un tableau associatif n'est pas un argument unique (bien qu'une référence à un tableau associatif soit, comme dans la réponse de Paul Tomblin).

} . "+"; } }

Ce qui vous manque fondamentalement, c'est qu'un tableau associatif n'est pas un argument unique (bien qu'une référence à un tableau associatif soit, comme dans la réponse de Paul Tomblin).

Il semble que vous deviez passer une référence à un hachage.

sub PrintAA
{
   my $test = shift;
   my $aa = shift;
   if (ref($aa) != "HASH") { die "bad arg!" }
   ....
}

PrintAA($foo, \%bar);

La raison pour laquelle vous ne pouvez pas faire de

my %aa = shift;

est parce que Perl aplatit tous les arguments d'une sous-routine en une seule liste, @_. Chaque élément est copié, le fait de passer par référence évite également ces copies.

Comme d'habitude, il y a plusieurs façons. Voici ce que Meilleures pratiques Perl , celui qui a le plus de succès pointeurs de style, doit dire sur le passage de paramètres à des fonctions:

Utilisez un hachage d'arguments nommés pour toute sous-routine ayant plus de trois paramètres

Mais puisque vous n'en avez que deux, vous pouvez vous échapper;) en les passant directement comme ceci:

my $scalar = 5;
my %hash = (a => 1, b => 2, c => 3);

func($scalar, %hash)

Et la fonction est définie comme suit:

sub func {
    my $scalar_var = shift;
    my %hash_var = @_;

    ... Do something ...
}

Cela pourrait être plus utile si vous pouviez montrer du code.

Toutes les méthodes ci-dessus fonctionnent, mais c’est toujours comme cela que je préférais faire les choses suivantes:

sub PrintAA ($\%)
{
    my $test       = shift;
    my %aa         = ${shift()};
    print "$test\n";
    foreach (keys %aa)
    {
        print "

Toutes les méthodes ci-dessus fonctionnent, mais c’est toujours comme cela que je préférais faire les choses suivantes:

PrintAA("test", %hash);

Remarque: j'ai également modifié un peu votre code. Les chaînes entre guillemets doubles de Perl vont interpréter "$ test" comme étant la valeur de $ test plutôt que la chaîne réelle '$ test' , de sorte que vous n'avez pas besoin de beaucoup de . s.

De plus, je me suis trompé sur le fonctionnement des prototypes. Pour passer un hachage, utilisez ceci:

PrintAA("test", %$ref_to_hash);

Pour imprimer une référence de hachage, utilisez ceci:

<*>

Bien sûr, vous ne pouvez plus modifier le hachage référencé par $ ref_to_hash car vous envoyez une copie, mais vous pouvez modifier un brut%% hash car vous transmettez-le comme une référence.

: $aa{

Toutes les méthodes ci-dessus fonctionnent, mais c’est toujours comme cela que je préférais faire les choses suivantes:

<*>

Remarque: j'ai également modifié un peu votre code. Les chaînes entre guillemets doubles de Perl vont interpréter "$ test" comme étant la valeur de $ test plutôt que la chaîne réelle '$ test' , de sorte que vous n'avez pas besoin de beaucoup de . s.

De plus, je me suis trompé sur le fonctionnement des prototypes. Pour passer un hachage, utilisez ceci:

<*>

Pour imprimer une référence de hachage, utilisez ceci:

<*>

Bien sûr, vous ne pouvez plus modifier le hachage référencé par $ ref_to_hash car vous envoyez une copie, mais vous pouvez modifier un brut%% hash car vous transmettez-le comme une référence.

}\n"; $aa{

Toutes les méthodes ci-dessus fonctionnent, mais c’est toujours comme cela que je préférais faire les choses suivantes:

<*>

Remarque: j'ai également modifié un peu votre code. Les chaînes entre guillemets doubles de Perl vont interpréter "$ test" comme étant la valeur de $ test plutôt que la chaîne réelle '$ test' , de sorte que vous n'avez pas besoin de beaucoup de . s.

De plus, je me suis trompé sur le fonctionnement des prototypes. Pour passer un hachage, utilisez ceci:

<*>

Pour imprimer une référence de hachage, utilisez ceci:

<*>

Bien sûr, vous ne pouvez plus modifier le hachage référencé par $ ref_to_hash car vous envoyez une copie, mais vous pouvez modifier un brut%% hash car vous transmettez-le comme une référence.

} = "$aa{

Toutes les méthodes ci-dessus fonctionnent, mais c’est toujours comme cela que je préférais faire les choses suivantes:

<*>

Remarque: j'ai également modifié un peu votre code. Les chaînes entre guillemets doubles de Perl vont interpréter "$ test" comme étant la valeur de $ test plutôt que la chaîne réelle '$ test' , de sorte que vous n'avez pas besoin de beaucoup de . s.

De plus, je me suis trompé sur le fonctionnement des prototypes. Pour passer un hachage, utilisez ceci:

<*>

Pour imprimer une référence de hachage, utilisez ceci:

<*>

Bien sûr, vous ne pouvez plus modifier le hachage référencé par $ ref_to_hash car vous envoyez une copie, mais vous pouvez modifier un brut%% hash car vous transmettez-le comme une référence.

}+"; } }

Remarque: j'ai également modifié un peu votre code. Les chaînes entre guillemets doubles de Perl vont interpréter "$ test" comme étant la valeur de $ test plutôt que la chaîne réelle '$ test' , de sorte que vous n'avez pas besoin de beaucoup de . s.

De plus, je me suis trompé sur le fonctionnement des prototypes. Pour passer un hachage, utilisez ceci:

<*>

Pour imprimer une référence de hachage, utilisez ceci:

<*>

Bien sûr, vous ne pouvez plus modifier le hachage référencé par $ ref_to_hash car vous envoyez une copie, mais vous pouvez modifier un brut%% hash car vous transmettez-le comme une référence.

Les arguments des fonctions sont aplatis dans un seul tableau (@_). Il est donc généralement plus facile de passer des hachages à fonctionner par référence.

Pour créer un hachage:

my %myhash = ( key1 => "val1", key2 => "val2" );

Pour créer une référence à ce hachage:

my $href = \%myhash

Pour accéder à ce hachage par référence;

%$href

Donc dans vos sous:

my $myhref = shift;

keys %$myhref;

Toutes les autres réponses ici à ce jour me semblent plutôt compliquées. Lorsque j'écris une fonction Perl, j'ai l'habitude de "développer". tous les arguments passés dans la première ligne de la fonction.

sub someFunction {
    my ( $arg1, $arg2, $arg3 ) = @_;

Ceci est similaire aux autres langues, où vous déclarez des fonctions en tant que

... someFunction ( arg1, arg2, arg3 )

Et si vous le faites de cette façon et que vous passez le hachage comme dernier argument, vous pourrez vous en passer, sans astuce ni magie particulière. Exemple:

sub testFunc {
    my ( $string, %hash ) = @_;
    print "$string $hash{'abc'} $hash{'efg'} $string\n";
}

my %testHash = (
    'abc' => "Hello",
    'efg' => "World"
);
testFunc('!!!', %testHash);

La sortie est comme prévu:

!!! Hello World !!!

Cela fonctionne car en Perl, les arguments sont toujours passés comme un tableau de valeurs scalaires et si vous passez un hachage, sa valeur clé / les paires sont ajoutées à ce tableau. Dans l'exemple ci-dessus, les arguments passés à la fonction en tant que tableau ( @_ ) sont en fait:

'!!!', 'abc', 'Hello', 'efg', 'World'

et '!!!' est assigné simplement à % string , tandis que % hash "avale" tous les autres arguments, en interprétant toujours un comme clé et le suivant comme valeur (jusqu'à ce que tous les éléments soient épuisés).

Vous ne pouvez pas transmettre plusieurs hachages de cette façon et le hachage ne peut pas être le premier argument, sinon il avalerait tout et laisserait tous les autres arguments non affectés.

Bien sûr, la même chose fonctionne pour array en dernier argument. La seule différence est que les tableaux ne font pas la distinction entre les clés et les valeurs, pour eux tous les arguments restants sont des valeurs et sont simplement poussés vers le tableau.

Utilisez le sous-répertoire suivant pour obtenir un hachage ou un hashref, quel que soit ce qui a été passé :)

sub get_args { ref( 

Utilisez le sous-répertoire suivant pour obtenir un hachage ou un hashref, quel que soit ce qui a été passé :)

printAA($firstarg,somearg=>1, anotherarg=>2)

Appelez votre fonction comme suit:

printAA($firstarg,{somearg=>1, anotherarg=>2})

Ou comme ceci (peu importe):

my(%hash) = ( 'aaa' => 1, 'bbb' => 'balls', 'ccc' => \PrintAA );

PrintAA("test", %hash);

Ou même comme ça (peu importe):

<*>

Salut!

[0] ) ? shift() : ( @_ % 2 ) ? {} : {@_}; } sub PrintAA { my $test = shift; my $aa = get_args(@_);; #then $aa->{somearg} #do something $aa->{anotherearg} #do something }

Appelez votre fonction comme suit:

<*>

Ou comme ceci (peu importe):

<*>

Ou même comme ça (peu importe):

<*>

Salut!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top