Pourquoi cette instruction de carte en Perl ne compile-t-elle pas?
Question
Cela échoue:
my @a = ("a", "b", "c", "d", "e");
my %h = map { "prefix- Cela échoue:
Not enough arguments for map at foo.pl line 4, near "} @a"
avec cette erreur:
my @a = ("a", "b", "c", "d", "e");
my %h = map { "prefix-" . Cela échoue:
my @a = ("a", "b", "c", "d", "e");
my %h = map { "prefix- Cela échoue:
Not enough arguments for map at foo.pl line 4, near "} @a"
avec cette erreur:
<*>
mais cela fonctionne:
<*>
pourquoi?
" => 1 } @a;
avec cette erreur:
<*>
mais cela fonctionne:
<*>
pourquoi?
=> 1 } @a;
mais cela fonctionne:
<*>
pourquoi?
" => 1 } @a;
avec cette erreur:
<*>mais cela fonctionne:
<*>pourquoi?
La solution
Parce que Perl devine un EXPR (une référence de hachage, par exemple) au lieu d’un BLOCK. Cela devrait fonctionner (notez le symbole '+'):
my @a = ("a", "b", "c", "d", "e");
my %h = map { +"prefix- Parce que Perl devine un EXPR (une référence de hachage, par exemple) au lieu d’un BLOCK. Cela devrait fonctionner (notez le symbole '+'):
<*>
" => 1 } @a;
Autres conseils
Je préfère écrire cela comme
my %h = map { ("prefix- Je préfère écrire cela comme
<*>
pour montrer l'intention, que je retourne une liste à 2 éléments.
" => 1) } @a;
pour montrer l'intention, que je retourne une liste à 2 éléments.
À partir de carte perldoc -f
:
"{" starts both hash references and blocks, so "map { ..."
could be either the start of map BLOCK LIST or map EXPR, LIST.
Because perl doesn’t look ahead for the closing "}" it has to
take a guess at which its dealing with based what it finds just
after the "{". Usually it gets it right, but if it doesn’t it
won’t realize something is wrong until it gets to the "}" and
encounters the missing (or unexpected) comma. The syntax error
will be reported close to the "}" but you’ll need to change
something near the "{" such as using a unary "+" to give perl
some help:
%hash = map { "\L À partir de carte perldoc -f
:
<*>", 1 } @array # perl guesses EXPR. wrong
%hash = map { +"\L À partir de carte perldoc -f
:
<*>", 1 } @array # perl guesses BLOCK. right
%hash = map { ("\L À partir de carte perldoc -f
:
<*>", 1) } @array # this also works
%hash = map { lc( À partir de carte perldoc -f
:
<*>), 1 } @array # as does this.
%hash = map +( lc( À partir de carte perldoc -f
:
<*>), 1 ), @array # this is EXPR and works!
%hash = map ( lc( À partir de carte perldoc -f
:
<*>), 1 ), @array # evaluates to (1, @array)
or to force an anon hash constructor use "+{"
@hashes = map +{ lc( À partir de carte perldoc -f
:
<*>), 1 }, @array # EXPR, so needs , at end
and you get list of anonymous hashes each with only 1 entry.
En outre, l’autre façon de faire ce que vous faites, en initialisant le hachage, vous pouvez procéder comme suit:
my @a = qw( a b c d e );
my %h;
@h{@a} = ();
Cela créera des entrées undef pour chacune des cinq clés. Si vous voulez leur donner toutes les vraies valeurs, faites ceci.
@h{@a} = (1) x @a;
Vous pouvez aussi le faire explicitement avec une boucle;
@h{ En outre, l’autre façon de faire ce que vous faites, en initialisant le hachage, vous pouvez procéder comme suit:
my @a = qw( a b c d e );
my %h;
@h{@a} = ();
Cela créera des entrées undef pour chacune des cinq clés. Si vous voulez leur donner toutes les vraies valeurs, faites ceci.
@h{@a} = (1) x @a;
Vous pouvez aussi le faire explicitement avec une boucle;
<*>} = 1 for @a;
Je pense que
map { ; "prefix- Je pense que
<*>
est plus idiomatique, dans la mesure où il est spécifié qu'il s'agit d'un bloc d'instructions et non d'une référence à un hachage. Vous commencez juste avec une déclaration nulle.
" => 1 } @a;
est plus idiomatique, dans la mesure où il est spécifié qu'il s'agit d'un bloc d'instructions et non d'une référence à un hachage. Vous commencez juste avec une déclaration nulle.