2016-12-22 1 views
3

は、匿名のslurpyパラメータの例があります:Perl 6シグネチャの匿名パラメータは値を破棄しますか? Perl 6の<a href="https://docs.perl6.org/type/Signature" rel="nofollow noreferrer">Signature docs</a>で

sub one-arg (@) { } 
sub slurpy (*@) { } 
one-arg (5, 6, 7); # ok, same as one-arg((5, 6, 7)) 
slurpy (5, 6, 7); # ok 
slurpy 5, 6, 7 ; # ok 

この周りのテキストは、パラメータの署名を満たすリストではなく、何についてである主な理由は何の文は、サブルーチンではありませんサブルーチンはそれを行います。

私はそれを試していましたが、1つ以上の項目のリストを取るサブルーチンを作ろうとしていました。私はそれらの名前を特に気にしませんでした。署名があっても、私はまだ@_の引数リストにアクセスできると考えました。

$ perl6 
To exit type 'exit' or '^D' 
> sub slurpy(*@) { say @_ } 
===SORRY!=== Error while compiling: 
Placeholder variable '@_' cannot override existing signature 
------> sub⏏ slurpy(*@) { say @_ } 

引数リストを取得する別の方法があり、または匿名のパラメータは、それらを捨てるん:あなたは、署名がない場合しかし、あなたは@_を取得しますか?型制約に関するセクションで使用されていますが、パラメータ値のいずれかを使用する例はありません。引き続き引数リストを取得できますか?

答えて

5

値は破棄されません。あなたはnextsame経由例のアクセスにそれをするために次のことができます。

multi access-anon(*@) is default { 
    say "in first candidate"; 
    nextsame; 
} 
multi access-anon(*@a) { 
    @a; 
} 
say access-anon('foo') 

出力:

in first candidate 
[foo] 

しかし、あなたの本来の目的(少なくとも1つの要素を持つ配列)を取得するために、あなたが実際にアクセスする必要はありませんリスト;

sub at-least-one(@ [$, *@]) { } 
at-least-one([1]); # no error 
at-least-one([]); # Too few positionals passed; expected at least 1 argument but got only 0 in sub-signature 
+0

あなたの少なくとも1つの例では、同じ問題に戻りませんか?これらのサブシステムの中には、依然としてパラメータへのアクセス権がありません。 'nextsame'は面白いですが、私はそのレベルの魔法を探していませんでした。 –

+0

@briandfoy:そうです。しかし、答えの一番下に示されているように、最初の '@'に '@ _ 'という名前を付けると、あなたがしようとしたことを効果的に得ることができます:' @ _'のすべての引数にアクセスできます。サブノリティの '$、* @'パラメータに '' 1つ以上の項目 ''の条件を適用するために使われた名前を指定します。 – smls

+0

あなたは何の問題について話していますか?変数にアクセスしたい場合は、その変数に名前をつけてください:-)。また、引数リスト全体にアクセスすることもできますが、名前を付ける必要もあります。 Perl 5でも、アクセスするための名前( '@ _ ')が必要です。 – moritz

2

@_を入力するには、署名を暗黙的または明示的に指定するか、両方を指定する必要があります。

sub implicit    {  say @_ } # most like Perl 5's behaviour 
sub explicit  (*@_) {  say @_ } 
sub placeholder   { $^a; say @_ } 

これも$_の暗黙のパラメータを持つことができるだけでなく

my &implicit =  {  say @_ } 
my &explicit = -> *@_ {  say @_ } 
my &placeholder =  { $^a, say @_ } 

ブロックをブロックに適用されますが、それがある場合@_が優先されます。

{  say $_ }(5) # 5 
$_ = 4; 
{ @_; say $_ }(5) # 4 

1人のプログラマが、それはあなたがそれがないと思うように動作すると思うかもしれ、または暗黙的な場合には次のようになりようにそれがslurpyであること、そしてもう一つは、それが取得すると思うかもしれませんので、このようにそれを行うには理にかなっていますすべての残りの引数。

sub identical ( @_   ) { say @_ } 
sub slurpy ( *@_ (@, *@)) { say @_ } # same as implicit 
sub slurpy2 ( **@_ (@, *@)) { say @_ } # non-flattening 
sub remaining (@, *@_   ) { say @_ } 

identical [1,2];  # [1 2] 
slurpy $[1,2],3,4,5; # [[1 2] 3 4 5] 
slurpy2 [1,2],3,4,5; # [[1 2] 3 4 5] 
remaining [1,2],3,4,5; # [3 4 5] 

@_も間違いとして添加してもよく、それはエラーを生成するような場合には好ましいであろう。


キャプチャパラメータを宣言せずに生の引数を取得する方法はありません。

sub raw-one (|capture (@)) { capture.perl } 
sub raw-slurpy (|capture, *@ ) { capture.perl } 

raw-one [1,2]; # \([1, 2]) 
raw-slurpy 1,2 ; # \(1, 2) 
+0

したがって、匿名パラメータ*はパラメータを非表示にするためアクセスできません。 –

+0

@briandfoyまあ... nqpを使ってRakudoに乗る方法はおそらくありますが、Perl 6にはそれを行うための明確な方法がありません。また、それを可能にするサブタイプに特性を追加することもできます。これはコンパイラーにとらわれないものでなければなりません。 –

+1

キャプチャにサブシグネチャを使用する必要はありません。 i.E.これはうまく動作します: 'sub raw(| capture、* @){キャプチャ} – timotimo

4

Perl 6の署名における匿名のパラメータは、値を破棄していますか?

あなたが関数のシグネチャに、いくつかの名前付きパラメータを使用して引数をキャプチャしない限り、はい、それは関数本体で使用できなくなります。 (PS:。彼らは文字通りモリッツの答えが示すように、しかし廃棄されていない)

私はまだでも署名で@_に引数リストへのアクセス権を持っているはずと考えました。

@_は、パラメータを使用する代わりではありません - それパラメータです。

すべての関数には、そのパラメータを指定する明確なシグネチャがあり、関数本体がその関数が渡される値を取得する唯一のメカニズムを表します。あなたが明示的に署名を書き出す場合

  1. は、それが使用されているものです。

    それは、関数のシグネチャを宣言するための3つの異なる方法があるだけのことです。

  2. あなたは関数の本体でプレースホルダパラメータ@_または$^fooなど)を使用する場合、コンパイラはあなたのための署名を構築するために、その情報を使用しています:
    say { $^a + @_ }.signature; # ($a, *@_)
  3. 上記のどちらも事実である場合、その後、署名は次のようになる。サブルーチンの場合
    • 、ゼロ引数受け付け1:として入手可能な、ゼロまたは1つの引数を受け入れ裸ブロックの場合
      say (sub { 42 }).signature; #()
    • 、一:全ての場合において
      say { 42 }.signature; # (;; $_? is raw)

、関数はコンパイル時に一義的な署名で終わります。 (すでに明示的なシグネチャを持つ関数で$^fooを使用しようとすると、コンパイル時エラーになります。)

はでそれをキャプチャすることを確認し、引数のリストを取得する別の方法はあります非anonymouysパラメータ。 @_としてアクセスできるようにしたい場合は、明示的な署名で書いてください。

私は[...]あなたはそのためのサブシグニチャを使用することができるより多くのアイテムの1

のリストを受け取り、サブルーチンを作成しようとしている:

sub foo (*@_ [$, *@]) { ... }; 

または代わりwhere制約:

sub foo (*@_ where .so) { ... }; 
+0

FWIW、' .elems> 0'はあまり良くありません。 '.so'を使う方が良いでしょう。ブール値をチェックしてください。 –

+0

@ZoffixZnet:更新されました。 – smls

関連する問題