2011-12-16 3 views
9

これは私が持っているものです。coderefの後にハッシュの構築を可能にするために、プロトタイプをどのように修正する必要がありますか?

use 5.14.0; 
use strict; 
use warnings; 

sub my_func(&$) { 
    my $coderef = shift; 
    my %attribs = @_; 
} 

これは私が達成したいものです。

my_func { 
    print 1; 
} first_attrib => "1",second_attrib => "2"; 

しかし、私はエラーToo many arguments for main::my_func at x.pl line 12, near ""2";"を受け取ります。コードレファレンスの後のパラメータがハッシュに変換されるように、プロトタイプをどのように変更すればよいですか?

答えて

8

sub my_func(&$)sub my_func(&%)に変更すると、コードが機能します。

first_attrib => "1",second_attrib => "2"はハッシュリファレンスではなくリストです。 friedoが指摘しているように、リストが奇数の要素を持つリストは望ましくない結果を生成し、use warningsという警告を生成しますが、リストをハッシュに割り当てることができます。

また、あなたが望むように見えるものを達成するために

sub my_func(&$) { 
    my $coderef = shift; 
    my ($attribs) = @_; 
} 

my_func { 
    print 1; 
} {first_attrib => "1",second_attrib => "2"}; 

にコードを変更することができます。

$attribsを括弧で囲む必要があるのは、配列をスカラーに割り当てると、配列の要素数だけが返されるためです。この時点で@_この配列である:単一の要素としてハッシュREFと

({first_attrib => "1",second_attrib => "2"}) 

($attribs) = @_; 

従って@_にハッシュリファレンスで$attribs点を作り、その最初の要素としてスカラー$attribsと無名配列を作成し、匿名のアレイに@_から要素を割り当て、要素によって要素にPerlを伝えます。

+2

それは '' first_attrib =>「1」、second_attrib =>「2」と言うことは、より正確なのはAです* list *、およびリストをハッシュに割り当てることができます。 – friedo

+0

@friedo:それは本当です。それを指摘してくれてありがとう。 – flesk

3

Perlのサブフォームの引数を実現する必要があります。あなたはハッシュを形成するために、コードリファレンスの引数リストの最初の要素と残りの要素を使用します。

#!/usr/bin/env perl 

use 5.14.0; 
use strict; 
use warnings; 

sub my_func(&@) { 
    my $coderef = shift; 
    my %attribs = @_; 
    $coderef->() for keys %attribs; 
} 

my_func { 
    print 1; 
} first_attrib => "1",second_attrib => "2"; 
+2

++の場合、プロトタイプが単に '(&@)'に変更された場合、コードは書かれた通りに呼び出して動作します。 – hobbs

+3

@hobbs:または、私の意見では、OPが達成したいことを考えれば、より直感的な、 '(&%)'です。 – flesk

関連する問題