2008-11-07 7 views
10

यह विफल रहता है:पर्ल में यह नक्शा कथन क्यों संकलित नहीं करता है?

my @a = ("a", "b", "c", "d", "e"); 
my %h = map { "prefix-$_" => 1 } @a; 
इस त्रुटि के साथ

:

Not enough arguments for map at foo.pl line 4, near "} @a" 

लेकिन यह काम करता है:

my @a = ("a", "b", "c", "d", "e"); 
my %h = map { "prefix-" . $_ => 1 } @a; 

क्यों?

उत्तर

21

क्योंकि पर्ल एक ब्लॉक के बजाय एक एक्सपीआर (उदाहरण के लिए हैश संदर्भ) का अनुमान लगा रहा है। यह (ध्यान दें '+' चिन्ह) काम करना चाहिए:

my @a = ("a", "b", "c", "d", "e"); 
my %h = map { +"prefix-$_" => 1 } @a; 

http://perldoc.perl.org/functions/map.html देखें।

11

perldoc -f map से:

  "{" 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$_", 1 } @array # perl guesses EXPR. wrong 
      %hash = map { +"\L$_", 1 } @array # perl guesses BLOCK. right 
      %hash = map { ("\L$_", 1) } @array # this also works 
      %hash = map { lc($_), 1 } @array # as does this. 
      %hash = map +(lc($_), 1), @array # this is EXPR and works! 
      %hash = map (lc($_), 1), @array # evaluates to (1, @array) 

      or to force an anon hash constructor use "+{" 

      @hashes = map +{ lc($_), 1 }, @array # EXPR, so needs , at end 

      and you get list of anonymous hashes each with only 1 entry. 
13

मैं के रूप में

my %h = map { ("prefix-$_" => 1) } @a; 

, आशय पता चलता है कि यह है कि मैं एक 2-तत्व सूची लौट रहा लिखने के लिए पसंद करते हैं।

6

इसके अलावा, अन्य तरीके से आप, क्या कर रहे हैं हैश आरंभ करने के लिए, अगर आप इस तरह कर सकते हैं:

my @a = qw(a b c d e); 
my %h; 
@h{@a} =(); 

कि पाँच कुंजी से प्रत्येक के लिए undef प्रविष्टियों का निर्माण करेगा। यदि आप उन्हें सभी सच्चे मूल्य देना चाहते हैं, तो यह करें।

@h{@a} = (1) x @a; 

आप इसे लूप के साथ स्पष्ट रूप से भी कर सकते हैं;

@h{$_} = 1 for @a; 
1

मुझे लगता है कि

map { ; "prefix-$_" => 1 } @a; 

जहाँ तक निर्दिष्ट करने कि यह बयान के एक ब्लॉक और नहीं एक हैश रेफरी के रूप में अधिक मुहावरेदार है। आप बस एक शून्य कथन के साथ इसे लात मार रहे हैं।