タイトル

Synopsis 8:キャプチャと Parcel

著者

Daniel Ruoso <daniel@ruoso.com>
 

機種

Created: 20 Sep 2009

Last Modified: 23 Jan 2010
Version: 2
 

イントロダクション

たいていのプログラム言語、パラメータをルーチン開始に送るために使われるデータ構造と異なり、(それであるメソッドあるいは sub)他のいずれのようにでも組込み型として言語にさらされる. これは Perl 6 ランタイム必要条件の最重要様相を表す。

さらにこのデータ構造が言語形式システムで目に見えるという事実に、それはそうじゃないキャプチャがデータの内部表示が変更を受け得ることを意味するネイティブの型だと想定する. ランタイムが想定することができる唯一のことはここで記述された API だ。

もちろん、それがキャプチャが最適化目的でそれ自身の内部データ構造によって実装されることを知っているときはいつでも、ランタイムは不正行為をすることができる、しかしそれは、オブジェクトが真を言うのと同じぐらい長いルーチンを呼び出すとき、外国の型の使用を許すべきだ.^does(Capture).

捕獲と Parcels は Perl 6 に同じくリストの多次元の基礎だ。 Perl 5 と異なり、平らになることは、それが明示的にユーザーによって必要とされない限り、起きない、そしてそれは、リストコンテキストを実施することによって、される。 もしあなたが項目コンテキストを使うなら、次元数は維持されるべきだ。

リストと項目コンテキストのほかに、同じく、単純化された方法で、呼び出される特別なコンテキスト「キャプチャコンテキスト」がある、しかしそれは実際に「延期されたコンテキスト」を意味する、キャプチャあるいは区画が現状のままで保持される方法でそれらである間にでコードで操られている。 これは、キャプチャの振る舞いを変えるかもしれないその通りにやる特徴を避けることに加えて、望まれない平らになることを避けるために有用だ。

これはキャプチャと Parcel がなぜ Perl 5 参照を置き換えるかの骨子だ、それらがあなたが送信データに1つの場所からもう1(つ・人)まで心を動かされないことを可能にする。 理由が Perl 6 のようにすべてがオブジェクトであるということである瞬間、もう本当に「値渡し」がない、あなたは常に参照を送っている、 Capture と Parcels はそれらにコンテキストを強制しないでただ他のオブジェクトを振る舞う。

キャプチャあるいは区画

Capture (位置の、そして名指された)ルーチンに送られたパラメータを保つオブジェクトであるParcel 位置の引数(けれどもそれはまだあなたに(彼・それ)らの名前によって名指されたものにアクセスさせる)から本当に名指された引数を区別しないいっそう基本的なデータ構造だ。

基本的な原因となっているコンセプトはリストとほとんど同じように Parcel が振る舞うということだ、しかし方法でそのノーが平らになることにおいてのコンテキストあるいは強要がされることは何も実施しない。 あなたが使うときPositional Parcel の上の API 、名指された引数のようなそれら一見あるいは位置の引数かにかかわらず、それはすべての目録に載っている品目を含むだろう。 例:

  1, 2, :a<b>
 

ここで表された区画は3つの位置の品目を持っていて、そしてあなたに完全に要素「a」にアクセスすることを許すAssociative 相互に作用しろ。 もしそれがルーチン呼び出しに引数として使用されていることがパーサーに明確であるなら、 Parcel が静的にキャプチャに変換されるかもしれない。

ではないが例えば名指された引数のための位置の情報を保持するのに要した、他方の、キャプチャ:

  foo(1,:a<b>,2)
 

呼び出しでルーチン foo に、ただ2つの守備の引数と1つの名指された引数だけがある、そしてあなたは「b」を見いだすことが可能じゃないであろうPositional 相互に作用しろ、けれどもただ結合性から。

Parcel からの分化とキャプチャはインラインの宣言の通常の使用を一貫しているようにしておくために重要だ、あなたが次のことをすると言おう:

  my $a = (0, :a<b>, 2);
  say $a[2];
 

もし我々がキャプチャを持っていた、そして同じデータ構造としての Parcel は、あなたは得ないであろうなら2 上記のコードの結果として、なぜなら、3ではなく、たった2つの位置引数があるから。 同じ例を使って:

  sub foo($p1, $p2, :$a) {...}
  foo(|$a);
 

区画がそうである収納ケースが変換したという点でキャプチャとそのために二人に打ち込んでいるか:a<b> ただ名前をつけられるようにだけ、位置引数としてもう目に見えない。

あなたが変換する途端に、キャプチャの中への Parcel 、あなたが再びオリジナルの区画を得ることが可能じゃないであろうことに注意を払え、なぜならキャプチャが名指された引数のポジションについての情報を保たないから。

Multidimensionality

おそらく Parcels と Capture の最も重要な仕事は Perl 6 にリストの多次元を実装することだ、これは演算子によってデータ構造の次元数を発見するために使われる障壁がそれの中の項目が何を実装するとしても区画あるいはキャプチャであることを意味する。 例えば:

  my $a = (1, (2, (3, 4)));
  say $a[1];
 

それで場合は、あなたは受けとるだろう2, (3, 4) (あるいはその特定の区画の .Str メソッドで実装されるものは何も)。

[更新:上の(人たち・もの)(そして下に続くものの多く)は区画についての最近のディスカッションに従わない;区画が項目割り当ての下で平らになる。 http://irclog.perlgeek.de/perl6/2009-09-23#i_1532822.] を見ろ

けれども、あなたはそうすることが可能であるべきだ:

  say $a[1;0];
 

それは戻ろうとしている2ほとんど同じがどちらとしてか :

  say $a[1][0];
 

けれども最初はそれを求めるいっそう便利そして optimizeable の方法を提供する。 もしあなたが値を得ることを望むなら4 そのデータ構造からあなたはそうする必要がある:

  say $a[1;1;1];
 

もしあなたが配列にその区画を割り当てるなら、平らになっていて、そうであるであろうことに注意を払え:

  my @a = 1, (2, (3, 4));
  say @a[3];
 

印刷するだろう4同時にそれが多次元を求めようとするという状態で、そのリストからの情報が失敗に終わるだろう:

  say @a[1;1;1];
 

配列の要素1として@a キャプチャあるいは区画、それが(そのために)できないではない.[] 演算子がそれをくまなく渡り歩く。

[推測:多次元のアクセスが、すなわち、通常の配列に入ることが可能であるべきであるかどうかはまだ明確じゃない:[1,[2,[3,[4]]]] ]

ただ、区画を作っているのは括弧じゃないことを悟ることは重要であるinfix:<,>.  括弧はただ sub - 区画を定義するために必要とされるだけだ。

他方、もしあなたが変数に区画をバインドするなら、それがどのシギルを使うかは本当に重要じゃない:

  my @a := (1, (2, (3, 4)));
  say @a[1;1;1]; # "4"
  say @a[3]; # failure
 

捕獲と Parcels は例えば多次元に関して同じように見られる:

  my $a = ((map { $_ * 2 }, 1..5),(map { $_ / 2 }, 1..5));
  say $a[0;0]; # 2
  say $a[1;0]; # 0.5
 

1つの項目以上そのキャプチャの中に同じように、もしそれぞれクロージャ回帰をマップしろ:

  my $a = ((map { $_ * 2, $_ / 2 }, 1..5),(map { $_ / 2, $_ * 2 }, 1..5));
  say $a[0;0;0]; # 2
  say $a[0;0;1]; # 0.5
  say $a[1;0;0]; # 0.5
  say $a[1;0;0]; # 2
 

プロセスが、それほど、 Parcels と Capture の中に否定するであろう平らになること:

  1, (2, (3, 4))
 

結果を遺贈しろ:

  1, 2, 3, 4
 

平らになった後で、他方 :

  1, [2, [3, 4]]
 

現状のままで残留するだろう。

コンテキスト延期

同じく「キャプチャコンテキスト」として知られていて、あなたがどのように所定の値のためにコンテキスト強要を延期することができるか定義する。 スカラーに割り当てることと同じぐらいシンプルな何かがあなたのために修正された値を手に入れるであろうコンテキスト強要を暗示するかもしれないから、それは基本的な特徴だ。

区画とキャプチャ両方が、あなたが後にどんなコンテキストでも応用して、そして、コンテキストがすぐに応用されるかのように、同じ結果を持つことができる方法で、現状のままで値を維持することが可能だ。

コンテキスト延期は実際は Perl 6 がなぜもう「wantarray」演算子をサポートしないかという理由だ、同様にそれは何にも置換を提供しない。 あなたが wantarray のような振る舞いを実装するべきである方法はそれぞれのコンテキストのために適切に強要をオーバーライドすることによってだ。 Contextual ::モジュールが Perl 5 にそのコンセプトの実装である報告。

あなたのコードでコンテキスト延期を使うために、あなたは2つのフォームで提出されることができる「キャプチャシギル」を使う必要がある:

  my ¢a = (1, (2, (3, 4)));
 

あるいは

  my @%a = (1, (2, (3, 4)));
 

後者は代替物としてあなたが7ビットで規約を維持することを望む状況のみに提供される。

[更新しろ:@%a キャプチャシギルとして - http://irclog.perlgeek.de/perl6/2009-09-21#i_1523801.] を見ろと割り出さないかもしれない

付加

どうか perl6 - 言語にエラーとフィードバックをポストしてくれ。 もしあなたが一般的なリストを作っているなら、どうかトピックによるメッセージを分離してくれ。