Synopsis 9:データ構造
Larry Wall <larry@wall.org>
Created: 13 Sep 2004 Last Modified: 4 Jan 2011 Version: 50
この概要はディテールで Perl 6 データ構造のデザインを論じた実在しない Apocalypse 9を要約する。 それは主に Perl 6 の存在する特徴がどのようにPDLの人々が数値的 Perl を書くことをより容易にするために結合するかの論議だった。
すべてのリストコンテキストはデフォルトまでにいい加減だ。 それらが最終的に、しかし、そうすることを強いられるときだけ、まだ平らになるかもしれない。 使うべき権限:eager
コンテキストとあなたが使わなければならないいい加減でないリストを受けとるために演算子をリストするflat 平らにすることを保証するべき演算子。 しかしながら、このようなコンテキストが一般に、とにかく終局の目的地によって供給される、それであなたは通常明示的である必要がない。
サイズを定められた低レベルの型が一般に、一般的な低レベルの型名前:にビットの数をアペンドすることによって、大部分の人たちに指命される
int1 int2 int4 int8 int16 int32 (aka int on 32-bit machines) int64 (aka int on 64-bit machines) int128 (aka int on 128-bit machines) uint1 (aka bit) uint2 uint4 uint8 (aka byte) uint16 uint32 uint64 uint128 num16 num32 num64 (aka num on most architectures) num128 complex16 complex32 complex64 (aka complex on most architectures) complex128 rat8 rat16 rat32 rat64 rat128 buf8 aka buf, a "normal" byte buffer buf16 a uint16 buffer buf32 a uint32 buffer buf64 a uint64 buffer
複雑な大きさがそれぞれの大きさを示すnum 合計よりむしろコンポーネント。 これは張筋 typenames に及ぶだろう、組込み型は同じぐらい元気もしそれらだ。 もちろん、典型的な張筋構造は配列の次元でただ反映される - しかし原則はまだ名前が単純な基底型のかけらの数に基づいていると考える。
unsizedな型int そしてnum アーキテクチャの標準の大きさに基づいた賛成int そしてdouble 実行時システムがコンパイルされるどんなCのバージョンででも。 それでint
典型的に意味するint32 あるいはint64、他方num 通常意味するnum64そしてcomplex 何でもの2を意味するnum そうであることが分かる。
ネイティブの少数点の周りの対称のためにratsが大きさの2倍(彼・それ)らの分母、そんなものについてそれである分子を持っているrat32 実際にそうしたint64 その分子のために。 注文製の有理数型がインスタンスを作ることによって作成されるかもしれないRational 2つの型と一緒のロール;もし両方の使われた型がネイティブの型であるなら、結果として生じている型はネイティブの型だと見なされる。
あなたは、もちろん、「ショート」あるいは「シングル」のような、追加の名前を関連づけるためにマクロあるいは型宣言を使うことが自由だ。 これらはデフォルトによって供給されない。 64ビットの整数型をサポートするように要求される Perl ではないの実装、あるいは根本的なアーキテクチャがそれらをサポートしないなら 128 ビット浮動小数点型。 16ビットの浮動小数点同じくこの意味でオプションであると見なされる.
そしてはい , an int1 ただ-1あるいは0だけを記憶することができる。 私は誰かがそれの用途について考えるであろうと確信している・・・。
これらが主に記憶域型を表すように意図されることに注意を払え;コンパイラは一般に、それと反対に宣言あるいは明白な投げることがないときにはより広い型ですべての中間結果を保つことが自由だ。 それを持つことができない場所で中間結果を記憶する試みが一般に、オーバーフローに警告を引き起こすだろう。
Underflow が実利的なコンテキストと明示的な丸め演算子の使用に依存して同じく警告するかもしれない。 デフォルト丸めモードからNum そうするためにInt 警告なしで小数部を切り落とすはずだ。
(警告が定義 resumable の例外によってであることに注意を払え;しかしながら、例外ハンドラがこのような警告を致命的な例外に変換するか、あるいは完全にそれを無視することが自由だ。)
記憶域型への明示的な特徴が記憶域の場所がそうするだろうというそんなものの記憶するべき実際の試みとしての例外をスローする同じ可能性を持っている。
IEEE と共に浮動小数点の型は、我々はインバンドでの使用に向かって偏見を受ける+Inf-InfそしてNaN これがベクトル処理と逐次制御方式にもっと友好的であると解釈されるから、例外をスローすることへの優先の値。 オブジェクトがそんなものをタイプするけれどもNum そしてInt
多分スローされない例外あるいは警告として、失敗の性質について補足情報を記憶するかもしれない。
その属性がすべて低レベルの値型であるクラスが構造体として振る舞うことができる。 (けれども、クラスの外部からのアクセスは、オブジェクトの直列化されたバージョンのアドレスが使われるか、あるいは、Cのような言語に相互に作用することに対して、生成されるときを除いて、ただアクセス機構を通して静かだ。)
このようなクラスがコンパクトに実際に記憶されるかどうかは実装次第だ、しかし、少なくとも読んで、そして同等のC構造に書き込むことが(ユーザーの見地から)浅薄に容易である限りにおいて、それはそのように振る舞うべきだ。 すなわち、直列化されるか、あるいはCの意見に deserialized されるとき、たとえそれがそれが実際に内部にクラスを表した方法じゃないとしても、それはC構造体のように見えるべきだ。
(少なくとも流れのいくらかの代用が使うように、こちらは解釈されるために存在するpack/ unpack.) もちろん、いい加減な実装がおそらくただいつもその直列化された書式でオブジェクトを飼うことが最も容易であることを見いだすだろう。 特に、簡潔な構造体の配列が(彼・それ)らの直列化された形式で記憶されなくちゃならない(次のセクション参照)。
Cプログラミング言語に存在する型のために、直列化されたマッピングはメモリにデフォルトまでに同じアラインメントと埋め草ルールの後に続くべきだ。 1バイトがそうであるより小さい整数が - 2の力の中にビットの数をパックした、それで1バイトが4つの2ビットの整数を持っている。 どのように、もしかするとクラスと結び付けられるパック / アンパック形式フォーマットで、あるいはクラスの奇妙な要素と一緒に、あるいはそれの下で奇妙な要素が宣言される型と一緒に、メモリにそれらを並べ広げるべきか決定するために十分な情報でユーザーによって宣言されないなら、2ビットの力じゃないデータのサイズがサポートされない。
mutators を持っていない簡潔な構造体が、パフォーマンス考慮以外そうで、それ自身値型であることに注意を払え、その人たちが一貫している限り思い出にそれのいくつの主張があるかは重要じゃない。 他方、 mutators を持っている構造体がいっそう標準の変更可能なオブジェクトのように振る舞わなくちゃならない。
荷造り連載は適切なバッファタイプに強要によって行なわれる。 荷を解くことはこのような簡潔な構造体の型に戻っているバッファー型の強要によって行なわれる。
標準的な配列インデックスが正方形の括弧を使って指定される。 標準的なインデックスが常に(「多次元の配列」参照)配列のそれぞれの次元でゼロで始まって、そして常に連続的だ:
@dwarves[0] = "Happy"; # The 1st dwarf @dwarves[6] = "Doc"; # The 7th dwarf @seasons[0] = "Spring"; # The 1st season @seasons[2] = "Autumn"|"Fall"; # The 3rd season
基本的な配列宣言が好む:
my @array;
不確定な長さの一次元配列を宣言する。 このような配列は自動的に拡張している。 多くの目的で、けれども、特定の大きさについて配列型を定義することは有用だ、そして、自動的に拡張する代わりに、失敗する形は、もしあなたが(彼・それ)らの宣言された次元数の外(に・で)アクセスしようとするならだ。 このような配列は井戸を割り当てて、そしてそれとしてアクセスするためにより速い傾向がある。 (言語は、しかしながら、オーバーフローに対してあなたを守り続けなくちゃならない - このごろ、それは信頼性問題だけじゃなくセキュリティー問題でもある。)
固定サイズの配列を宣言するために、その名前:のすぐ後に正方形の括弧で要素のその最大値を指定しろ
my @dwarves[7]; # Valid indices are 0..6 my @seasons[4]; # Valid indices are 0..3
介入している空白文字が名前と大きさ仕様の間に認められない、しかし「unspace」が許される:
my @values[10]; # Okay my @keys [10]; # Error my @keys\ [10]; # Okay
正方形の括弧が、あなたが同様「ドットを打たれた」フォームを使うことができないように、実行時演算子ではなく、コンパイル時宣言詞であることに注意を払え:
my @values.[10]; # An indexing, not a fixed-size declaration my @keys\ .[10]; # Ditto
配列の定義されたレンジの外(に・で)インデックスにアクセスしようと試みることは失敗するだろう:
@dwarves[7] = 'Sneaky'; # Fails with "invalid index" exception
しかしながら、それはレンジあるいはシーケンスイテレータが、そのミン値が正当な添え字である限り、配列の終わりの外に及ぶように正当だ;右辺値として使用されるとき、レンジはただ正当な場所だけをマップするために必要に応じて取り除かれる。 (左辺値、何としてでも使用されるとき、それがそうすることができる実在しない添え字生成 WHENCE 代理人が新しい値を受け取って、そしてそれを必要とする何でも autovivify する。)
明示的に配列を自動的に延長している標準を指定することは同じく可能だ:
my @vices[*]; # Length is: "whatever"
# Valid indices are 0..*
添え字が配列を自動的に拡張することについての終わりの外に及んでレンジあるいはシーケンスイテレータを含んでいることに対して、レンジはその次元の宣言されたサイズよりむしろ配列の実際の現在のサイズに取り除かれる。 それはそれほど、終わりの後に、1(人・つ)を始めるこのようなレンジのためにそれを許される
@array[0..*]
ただ Nil もしを返す@array たまたま空だ。 しかしながら、
@array[1..*]
レンジの分があまりにも大きいから、失敗するだろう。
それほどこれら的なルールがあなたが言うかどうかは重要じゃないことを意味することに注意を払え
@array[*] @array[0 .. *] @array[0 .. *-1]
なぜならそれらがすべて同じことを意味することになるから。
左の終わりに自(己・動)切り捨てがない。 書くことはそれほど難しくない0そしてインデックスがそこ(に・で)常に始める水準。
特殊形式として、添え字宣言が付け加えるかもしれない:map そのクロージャを通してすべてのインデックス値が地図に表わされるはずであることを示して、クロージャを供給している修飾子。 例えば、添え字が循環していると宣言されるかもしれない:
my @seasons[4:map(*%4)];
この場合、すべての数の値はとられる、レンジ打切りではなく、法4が今までに起きることができる。 もしあなたが言うなら
@seasons[-4..7] = 'a' .. 'l';
それから3つの時と配列が終わる要素が書かれるそれぞれ['i','j','k','l']. マッピング関数はわずかな値を返すことを許される;インデックスはそうだろうfloor その値について。
(その0さらに少なく数のインデックスを使うことはまだ非合法だ。) 1(人・つ)は、数がそれらが否定的なインデックスを作り出すほど小さくない限り、例えば、対数でインデックスをマップすることができた。
もう1つの使用がスロットにさえ正数を、そして奇妙なスロットに負数をマップすることであるかもしれない、それであなたは、(データが対称的じゃないとき、 Perl があなたのために最大限によって使われた平らな、そして奇数のスロットを追跡しないであろうけれども)、対称的およそ0であるインデックスを受ける。
値の型が配列のそれぞれの要素で記憶される(通常Any 特定されていない型のために)明示的に指定されることができるあまりにも、外部としてof 型:
my num @nums; # Each element stores a native number my @nums of num; # Same my Book @library[1_000_000]; # Each element stores a Book object my @library[1_000_000] of Book; # Same
代わりに、要素記憶域型は(サブルーチン定義とほとんど同じような)次元指定子の部分として明示されるかもしれない:
my @nums[-->num]; my @library[1_000_000 --> Book];
形式の宣言で:
my bit @bits; my int @ints; my num @nums; my int4 @nybbles; my buf @buffers; my complex128 @longdoublecomplex; my Array @ragged2d;
低レベルの型のプレゼンスは Perl にそれが「ぎっしり詰まった記憶域」で配列を実装することが自由であると教える、すなわち、かなりのメモリがなしに指定された型の連続的である(か、あるいは実際的であるのと同じぐらい連続的な)要素を含むという状態で、何でも典型的にそれをボックス化することが当てはまるオブジェクトが未分化のスカラーだと想像する。 (Perl は本当に一生懸命試みる、オブジェクト - これがそうであるように、あなたがそれらを扱うとき、これらの要素をオブジェクトのように見えさせることはオートボクシングを呼び出した。)
明示的に固定サイズの(こと・もの)であると宣言されないなら、このような配列は普通の Perl 配列とまったく同じように(もう1つの記憶場所に、あるいはツリー構造を使って時折データブロックをコピーすることについての価格で)自動的に拡張している。
配列がそうであるコンパクトでなぜなら対応するバッファー型と交換可能なたいていの目的。 例えば、シギルを別として、これらは同等の宣言だ:
my uint8 @buffer; my buf8 $buffer;
(注意しろ:もしあなたが実際にそれらの両方ともを言ったなら、シギルが名前の一部だから、あなたはまだ2つの異なった名前を受けとるだろう。)
それで与えられた@buffer あなたは言うことができる
$piece = substr(@buffer, $beg, $end - $beg);
そして与えられた$buffer あなたは同じく言うことができる
@pieces = $buffer[$n ..^ $end];
数であると同じように、添え字化することはまだ要素を引き抜くとは、注意する、ただsubstr() 同じ型のバッファーを返す。
Cプログラミング言語、マッピングに存在する型のためにメモリに同じ整列法則に従うべきだ、少なくとも何でもないときにはそれと反対の宣言。 Cポインター型に、何でもインタフェースすることに対して、バッファー型がそのメモリポインタのために使われるかもしれない; しかしながら、バッファーがその長さを知っているのに対して、Cでその長さが典型的に別個の引数としてパスされなくちゃならないことに注意を払え、それで、 Perl がC.によって我々の上に遺言で譲られてすべてのバッファー超過バグを継承しないように、Cインターフェイシングコードは可能なときならいつでもこれをサポートする必要がある。 Cポインタが決してそうであるべきじゃない Random が変換しなかった、から長さが同じく知られていないならバッファー。
(strlen () への Any 呼び出しが一般にセキュリティーホールだと見なされるべきだ。)
バイトでのバッファタイプが一緒に見いだされるかもしれない何ものサイズ.bytes
メソッド、たとえ型であるとしてもバッファー要素についてではないbyte. (文字列がそれらバイト単位のサイズでただそれらが(彼・それ)らの最小抽出レベルとして希望を抱いて周知のエンコーディングで、バッファー型をサポートするかどうか尋ねられるかもしれない。 さもなければあなたは若干のバッファー型の中にもっとレベルが高い抽象概念から明示的にそれらをコード化しなくちゃならない。)
Perl 6 配列は1次元であるように制限されない(それはただデフォルトだ)。 多次元の配列を宣言するために、あなたは次元長さのセミコロンによって分離されたリストでそれを指定する:
my int @ints[4;2]; # Valid indices are 0..3 ; 0..1 my @calendar[12;31;24]; # Valid indices are 0..11 ; 0..30 ; 0..23
配列が同じく固定されていて、そして次元を自動的に延長することについての混合で定義されるかもしれない。 例えば、1日に1年と24時間に常に12カ月がある、しかし日数がその月に変化することができる:
my @calendar[12;*;24]; # day-of-month dimension unlimited/ragged
あなたは同様に形のためにスライスをパスする(何についてでも次元数)ことができる:
@shape = 4, 2; my int @ints[ ||@shape ];
prefix:<||> 演算子がセミコロンレベルでセミコロンリストの中に傾きを補間挿入する。
形は宣言でただ最初の用途に関して配列がどのように autovivify するであろうか明示するが、それによって実際のコンテナオブジェクトの属性となる。 他方、形は実行時において同じく明示的なコンストラクタによって完全に供給されるかもしれない:
my num @nums = Array of num.new(:shape(3;3;3)); my num @nums .=new():shape(3;3;3); # same thing
多次元の配列がセミコロンリストによってインデックスを付けられる、そしてそれは本当に変装したリストのリストだ。 それぞれの部分リストが1切れの1つの特定の次元だ。 それで:
@array[0..10; 42; @x]
本当に短く何かのために同種のものだ:
@array.postcircumfix:<[ ]>( (0..10), (42), (@x) );
メソッドの内部**@slices パラメータが添え字を依存しない3に変えるSeq 1つの他とは無関係にいい加減に読まれることができるリスト。 (それが順番にそれぞれの次元を薄く切る(とき・から・につれて・ように)、添え字化するものが左から右に典型的にそれらを使うであろうけれども)
それに注意しろ:
@array[@x,@y]
常に最も外側の次元で1次元のスライスとして解釈される、同じがどちらとしてか:
@array[@x,@y;]
あるいはいっそう冗長に:
@array.postcircumfix:<[ ]>( ((@x,@y)) );
使用コンマレベルよりむしろセミコロンレベルで配列を間にはさむことprefix:<||> 演算子:
@array[||@x]
匹敵するものがどちらへか
@array.postcircumfix:<[ ]>( ((@x[0]), (@x[1]), (@x[2]), etc.) );
配列の次元が宣言されるかもしれない Any 「*」どのケースで、その次元はそうするだろう自動的に拡張する. 典型的にこれは最終の次元でぼろを着た配列を機能上配列の配列と等しくするために使われるだろう:
my int @ints[42; *]; # Second dimension unlimited/ragged push(@ints[41], getsomeints());
何以外でも配列の次元が自動的に拡張していると宣言されるかもしれない:
my @calendar[12;*;24]; # day-of-month dimension unlimited/ragged @calendar[1;42;8] = 'meeting' # See you on January 42nd
「hyperwhatever」を使って、配列が次元の任意の数を持っていることを明示することは同じく可能である(**)指定期間の末、次元の仕様:
my @grid[**]; # Any number of dimensions my @spacetime[*;*;*;**]; # Three or more dimensions my @coordinates[100;100;100;**]; # Three or more dimensions
それに注意しろ** それが意味する何かのために速記だ||(* xx *)余分の次元が任意のサイズのすべてであるように。 固定サイズ次元の任意の数を指定するために、書け:
my @coordinates[ ||(100 xx *) ];
もしあなたが多数の首尾一貫してサイズを定められた次元を定義する必要があるなら、この構文は同じく都合が良い:
my @string_theory[ ||(100 xx 11) ]; # 11-dimensional
Any 配列が同じくゼロベースである必要がないユーザー定義のインデックス、単調、あるいは整数の第2セットをさえ与えられるかもしれない。 標準的な配列インデックスが常にゼロ、何ものインデックスが始めるかもしれないユーザー定義のとして何の有限の値でも始めるのに対して可算の型。 標準的なインデックスは常に連続的だ、しかしユーザー定義のインデックスはただ別で、そして可算のシーケンスであることが必要であるだけだ。
ユーザー定義のインデックスのセットを定義するために、弓カッコのセットで配列名前:のすぐ後にそれぞれの次元のインデックス(あるいは可算の型の名前)の明示的か、あるいは可算のリストを指定しろ
my @dwarves{ 1..7 };
my @seasons{ <Spring Summer Autumn Winter> };
my enum Months
«:Jan(1) Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec»;
my @calendar{ Months; 1..31; 9..12,14..17 }; # Business hours only
インデックスが同じく代わり弓カッコで指定されるユーザー定義のとしての配列ルックアップが括弧を同点にする:
@dwarves{7} = "Doc"; # The 7th dwarf
say @calendar{Jan;13;10}; # Jan 13th, 10am
ユーザー定義のインデックスがただ第2の、非標準の配列の「ビュー」を提供する;原因となっているコンテナは同じままでいる。 それぞれの次元でのそれぞれのユーザー定義のインデックスがその次元の標準的な(ゼロ - 基礎を置かれた)インデックスに戻って1対1で地図に表わされる。 それで、前の定義という条件のもとで:
maps to
@dwarves{1} ------> @dwarves[0]
@dwarves{2} ------> @dwarves[1]
: :
@dwarves{7} ------> @dwarves[6]
そして:
maps to
@seasons{'Spring'} ------> @seasons[0]
@seasons{'Summer'} ------> @seasons[1]
@seasons{'Autumn'} ------> @seasons[2]
@seasons{'Winter'} ------> @seasons[3]
@seasons<Spring> ------> @seasons[0]
@seasons<Summer> ------> @seasons[1]
@seasons<Autumn> ------> @seasons[2]
@seasons<Winter> ------> @seasons[3]
そして:
maps to
@calendar{Jan;1;9} ------> @calendar[0;0;0]
@calendar{Jan;1;10} ------> @calendar[0;0;1]
: :
@calendar{Jan;1;12} ------> @calendar[0;0;3]
@calendar{Jan;1;14} ------> @calendar[0;0;4]
: :
@calendar{Feb;1;9} ------> @calendar[1;0;0]
: :
@calendar{Dec;31;17} ------> @calendar[11;30;7]
ユーザー定義のインデックスは(すなわち標準的なインデックスとまったく同じように)自由形式だが、上端だけの上であり得る。 すなわち、あなたが明示することができる:
my @sins{7..*}; # Indices are: 7, 8, 9, etc.
けれどもそうじゃない:
my @virtue{*..6};
my @celebs{*};
これらの最後の2は最初のインデックスがないから、そして従って方法で標準的なゼロベースのインデキシングスキームに戻っている否定的なユーザー定義のインデックスの無限をマップすることを可能にされない。
暗黙的にユーザー定義のインデックスのセットを宣言することは(それぞれの次元でまだゼロベースである)井戸として配列の標準的なインデックスを宣言する。 このような配列はいずれかの表記法を使ってアクセスされることができる。 標準的なインデックスは「序数の」ポジション、利用者指定インデックスの独立に言及する容易な方法を提供する:
say "The first sin was @sins[0]"; # First element, no matter what @sin's user-defined indexes are
もし配列が固定インデックス(スタンダードあるいはユーザー定義の)で定義されるなら、何定義も失敗するであろうそれが指定されなかったインデックスを使おうと試みることに注意を払え。 例:
my @values{2,3,5,7,11}; # Also has standard indices: 0..4
say @values[-1]; # Fails (not a valid standard index)
say @values{1}; # Fails (not a valid user-defined index)
say @values{4}; # Fails (not a valid user-defined index)
say @values[5]; # Fails (not a valid standard index)
say @values{13}; # Fails (not a valid user-defined index)
さらに、もし配列がユーザー定義のインデックスで指定されなかったなら、何でもそれにインデックスを付けようと試みるとして.{} 失敗するだろう:
my @dwarves[7]; # No user-defined indices;
say @dwarves{1}; # Fails: can't map .{1} to a standard .[] index
いつ:k:kvあるいは:p 部分配列に適用される、それはスライスを生産するために使われた種類のインデックスを返す:
@arr[0..2]:p # 0=>'one', 1=>'two', 2=>'three'
@arr{1,3,5}:p # 1=>'one', 3=>'two', 5=>'three'
副詞がそれほど、項にではなく、演算子にだけ適用されるかもしれない:k:kvそして:p フルの配列に適用されないかもしれない。 しかしながら、あなたは副詞をキーのセットが切望されることを示すことができる Zen 断片に適用してもよい:
my @arr{1,3,5,7,9} = <one two three four five>;
say @arr[]:k; # 0, 1, 2, 3, 4
say @arr{}:k; # 1, 3, 5, 7, 9
.keys メソッドが同じくすべての存在する要素のキーを返す。
多次元の配列のためにそれぞれのキーがそれぞれの次元のために1つの値を含んでいるリストだ。
.shape メソッドが同じくこのような配列に取り組む;それはそれぞれの次元のために正当なキーの断片を返す。 無限の次元を表している構成要素リストはいい加減に必ず表される。
(それに注意する.shape メソッドが可能なキーを返す、しかし重要なスライス次元ではないの直積はすべてのケースで存在する要素にインデックスを付けることを約束した。 すなわち、このではないが使用中のキーの現在の組み合わせを反映するように意図される(使用:k それのために).
あなたがこれらの2つのフォームを識別しなければならないとは、注意しろ:
@array[].shape # the integer indices
@array{}.shape # the user-defined indices
何の中ででも配列ルックアップ(かどうかとして.[] あるいは.{})、「主役を演じるものは何も」「すべてのインデックス」ということを示すために使われることができる. 「すべて」の意味は配列の定義の上にここで依存する。 もし指定された前のインデックスがないなら、星は「現在割り当てられた要素のすべてのインデックス」を意味する:
my @data # No pre-specified indices
= 21, 43, 9, 11; # Four elements allocated
say @data[*]; # So same as: say @data[0..3]
@data[5] = 101; # Now six elements allocated
say @data[*]; # So same as: say @data[0..5]
もし配列が前もって宣言された固定インデックス(スタンダードあるいはユーザー定義の)で定義されるなら、星は「すべての定義されたインデックス」を意味する:
my @results{1,3...99} # Pre-specified indices
= 42, 86, 99, 1;
say @results[*]; # Same as: say @results[0..49]
say @results{*}; # Same as: say @results{1,3...99}
あなたは、使うことによって、同様、配分されていない要素を除くことができる:v 副詞:
say @results[*]:v; # Same as: say @results[0..3]
say @results{*}:v; # Same as: say @results{1,3,5,7}
あるいは、「zen スライス」を使うことによって:
say @results[]; # Same as: say @results[0..3]
say @results{}; # Same as: say @results{1,3,5,7}
A「主役を演じるものは何」でも同じく、スライスの中で、レンジの出発点として使われることができる、その場合それは「最初のインデックスから」ことを意味する:
say @calendar[*..5]; # Same as: say @calendar[0..5]
say @calendar{*..Jun}; # Same as: say @calendar{Jan..Jun}
say @data[*..3]; # Same as: say @data[0..3]
レンジの終端として、ただ1つだけの「何でも」が、(もし固定インデックスが定義されたなら)、「最大の指定されたインデックスに」ことを意味する:
say @calendar[5..*]; # Same as: say @calendar[5..11]
say @calendar{Jun..*}; # Same as: say @calendar{Jun..Dec}
あるいは「最も大きい割り当てられたインデックスに」(もし固定インデックスがないなら):
say @data[1..*]; # Same as: say @results[1..5]
「主役を演じるものは何」でも上記のいつとは異なって作用する、それは標準的なインデックス以内で数として取り扱われる。 それが配列の長さに評価するこのケースで。 これは後方に、あるいは前方へ配列の終わりから数えるクリーンで、そして一貫した方法を提供する:
@array[*-$N] # $N-th element back from end of array @array[*+$N] # $N-th element at or after end of array
もっと特定すると:
@array[*-2] # Second-last element of the array @array[*-1] # Last element of the array @array[+*] # First element after the end of the array @array[*+0] # First element after the end of the array @array[*+1] # Second element after the end of the array @array[*-3..*-1] # Slice from third-last element to last element @array[*-3..*] # (Same thing via range truncation)
(もし特定の配列次元がインデックスを直したなら、何でも、以前に記述されたレンジ打切りのケースを除いて、最後の定義されたインデックスが失敗するであろう後、要素にインデックスを付けようと試みることに注意を払え。)
添え字がモジュール式であると宣言されない限り、否定的な添え字は決してスタンダード添え字を許可されていない。
Perl 6 意味規則は中断(微妙なランタイムエラーのソース)にインデックスを付けるのを避けて、そして配列の両端に両方向に序数のアクセスを提供する。
時折一つのルックアップでスタンダードとユーザー定義のインデックスを混ぜることが可能であることは都合が良い。
1以内.[] あなたが使うことができるインデキシング演算*{$idx} 変換するために、ユーザー定義のインデックス$idx 標準的なインデックスに。 すなわち、:
my @lengths{ Months } = (31,28,31,30,31,30,31,31,30,31,30,31);
@lengths[ 2 .. *{Oct} ] # Same as: @lengths[ 2 .. 9 ]
同様に、中.{} あなたが使うことができるインデキシング演算*[$idx]
標準的なインデックスからユーザー定義のまで変換するために:
@lengths{ *[2] .. Oct } # Same as: @lengths{ Mar .. Oct }
言い換えれば、インデキシング演算の中で配列として扱われるとき、* 索引作成済み配列のインデックスの配列のように振る舞うことによって、あなたに基準とユーザー定義のインデックスの間に変換することを許す。 多次元の配列ルックアップの中でスタンダードとユーザー定義のインデックスを混ぜることに対して、これは特に有用だ:
# First three business hours of every day in December...
@calendar{Dec; *; *[0..2]}
# Last three business hours of first three days in July...
@calendar[*{July}; 0..2; *-3..*-1]
この特徴を拡張して、あなたは使うことができる** 索引操作の中でそれが添字付き配列の固定されている次元数のすべてのインデックスの多次元配列であるかのように:
# Last three business hours of first three days in July...
@calendar{ July; **[0..2; *-3..*-1] }
# Same...
@calendar[ **{July; 1..3}; *-3..*-1]
名指された引数と帰りの型を指定するために最終の標準のシグネチャーを含めて、種々の型の添え字宣言を積み重ねることは同じく可能だ:
my @array[10]{'a'..'z'}(:$sparse --> MyType);
[注意しろ:最終のシグネチャー構文は今のところただ予約されて、そして期待されない、からもしそれが何かを意味するなら、我々がそれが本当に何を意味するか理解するまで、働け。]
配列@array 宣言時にPDLにタイされることができる:
my num @array[||@mytensorshape] is PDL; my @array is PDL(:shape(2;2;2;2)) of int8;
PDLは型を仮定するべき許可だnum デフォルトまでにいつもの単純なスカラーよりむしろ。 (そして一般に、型インフォメーションはただそれがそうするであろうものに関係している「タイ」実装に提供される。
データ構造が無視するかもしれない若干数型「について」、そしてただ一般的なスカラーとしてすべてを記憶する. ...残念だ。)
デフォルトによっての配列は1次元だ、しかしどんな次元数でも実装によってサポートされるようにすると宣言されるかもしれない。 あなたはスカラーとまったく同じように配列を使ってもよい - 主な警告はあなたがバインディングを割り当てよりむしろコピーしないで1(人・つ)を設定するために使わなければならないということだ:
@b := @a[0,2,4 ... *]
PDLで特に、それぞれ配列全体よりむしろ個別の要素のこのかもしれない別名。 @ bへの修正が反映される可能性が高いように、 @ の中に a. 支持しろ。 (けれども多分 PDLers はそれのために異なった表記法の方を好むだろう。)
配列の次元数は変数に宣言されるかもしれない、しかし、それがどのように作成されたかについて、配列の実際の次元数は依存する。 これらの見方を和解させることは特定の配列実装のために仕事だ。 宣言された次元数が実際の次元数とマッチするに違いないということは必ずしも本当でない。 配列変数が慎重に異なった次元数で実効値についての異なった「意見」を提供すると宣言されることは非常に可能だ:
my int @array[2;2] is Puddle .= new(:shape(4) <== 0,1,2,3);
再び、それらの考えを和解させることは、実装に、上がっているPuddle
この場合。 トレイトシステムは、何にでも希薄さ、見すぼらしさと triangleness のような非 rectangleness の種々のフォームについて考えを含めて、必要とされるメタデータをパスするのに十分柔軟だ。
実装はおそらく何についてもあら捜しをするべきだ、けれどもそれがそうしないメタデータが認知する。 実装は何も拒絶するために確かに自由だ、そうしないオブジェクトが則する、から変数のシェイプ必要条件。
添え字が配列の「スライス」を示す。 配列のそれぞれの次元が別に薄く切られる、それで多次元のスライス添え字がスライス部分リストのセミコロンによって分離されたリストとして供給されるかもしれない。 3次元のスライスがこれのように見えるかもしれない:
@x[0..10; 1,0; 1,*+2...*]
それは実装次第であるの@x この添え字がどれほど積極的に、あるいはいい加減に評価されるか、そしてスライスがコピーすることを必要とするかどうか決めるために。 (PDLの人々は一般にそれがただその値が古い(の・もの・人)へと支持する新しい人たちがエイリアスを配列する事実上のPDLを産み出すことを望むだろう。)
もちろん、要素がシングルを供給してただ選択されることができるシングルが値にインデックスを付ける、からそれぞれリストを切れ:
@x[0;1;42]
すべての多次元の配列型のために、それが添え字をカスケードにしたことは期待される:
@x[0][1][42] @x[0..10][1,0][1,*+2...*]
失敗するか、あるいは同等のセミコロンが添え字化すると同じ結果を産み出すだろう:
@x[0;1;42] @x[0..10; 1,0; 1,*+2...*]
たとえカスケードにされた添え字フォームが、後の添え字が使うべき一時的なスライスオブジェクトを作成することによって、非能率的に実装されなくちゃならないとしても、組込み配列型がどちらにも成功するために期待される。 (ユーザー定義の型がカスケードにされた書式をサポートしないことに決めるかもしれない、しかしもしそうであるなら、それらが異なった意味規則を供給するよりむしろ失敗するべきだ。) 結果として、宣言された状態の組込み型のために、カスケードにされた添え字の適切な数は常にセミコロン書式の中に最適化されるかもしれない。
文レベルで、セミコロンが現在の展開式を終結する。
まあ構造をかっこでくくっている何の中ででも、セミコロンが観念的にその解釈がコンテキストに依存する多次元のスライスの部分リストを分離する。 リストがその部分リストのそれぞれを入れるこのようなセミコロンParcelそれがどこか(に・で)バインドされるまで、部分リストのコンテキストを延期する。 これらの部分リストの記憶域はリストの内部機構で隠される。 リスト全体がスライスコンテキストの中にバインドされない限り、それはリストのリストを作成しない。
一つの次元の配列が、それらが配列のシングル次元でリスト添え字をスライスとして取り扱うであろうことを意味して、単純なスライス添え字を期待する。 多次元の配列は、他方、どのようにそれぞれの次元のために多次元のスライス、1で subslice 、を扱うべきか知っている。 あなたはすべての次元を指定する必要がない;もしあなたがそうしないなら、特定されていない次元は「wildcarded」だ。 あなたがそうしたとして:
my num @nums[3;3;3];
それから
@nums[0..2]
同じであるけれども
@nums[0..2;]
同じがどちらとしてか
@nums[0,1,2;*;*]
けれどもあなたは、あなたが実際にさらに何(個・人)の次元があるか知らなくはない限り、とにかくただ良いドキュメンテーションのために多分最後のフォームを書くべきだ。 そのケースの使用のために**:
@nums[0,1,2;**]
もしあなたがそれを欲したなら0..2 意味するべきレンジ
@nums[0;1;2]
それは使うのに十分良くない| それがそれほど、コンマレベルで、補間挿入されるから、演算子を前接続しろ:
@nums[ |(0,1,2) ]
ただ手段
@nums[ 0,1,2 ];
その代わりに、セミコロンレベルで補間挿入されるために、あなたは使う必要がある|| 演算子を前接続しろ:
@nums[ ||(0..2) ]
ゼロ - 次元のスライス:
@x[]
ゼロではなく、すべてを欲すると考えられる。 Perl 6 (Perl 5 と異なり、)が括弧なしでそのままの配列を補間挿入しないであろうから、それは特に有用だ:
@x = (1,2,3); say "@x = @x[]"; # prints @x = 1 2 3
リストは Perl 6 にいい加減だ、そしてスライスリストは例外じゃない。 特に、リストジェネレーターは仮にもであるそれらの必要まで平らになっていない。 それでPDL実装がこれらのジェネレーターから値を盗んで、そしてそれらの周りに「だらだらと過ごす」ことが自由だ:
@nums[$min ..^ $max] @nums[$min, *+3 ... $max] @nums[$min, *+3 ... *] @nums[1,*+2...*] # the odds @nums[0,*+2...*] # the evens @nums[1,3...*] # the odds @nums[0,2...*] # the evens
このような Perl 5 PDL定義を書き直すために:
pp_def(
'inner',
Pars => 'a(n); b(n); [o]c(); ', # the signature, see above
Code => 'double tmp = 0;
loop(n) %{ tmp += $a() * $b(); %}
$c() = tmp;' );
あなたは漠然とこれに似ている何かを解析するマクロを書くことを望むかもしれない:
role PDL_stuff[::TYPE] {
PDLsub inner (@a[$n], @b[$n] --> @c[]) {
my TYPE $tmp = 0;
for ^$n {
$tmp += @a[$_] * @b[$_];
}
@c[] = tmp;
}
}
それがこのような何かに変わるところ(に・で):
role PDL_stuff[::TYPE] {
multi inner (TYPE @a, TYPE @b --> TYPE) {
my $n = @a.shape[0]; # or maybe $n is just a parameter
assert($n == @b.shape[0]); # and this is already checked by PDL
my TYPE $tmp = 0;
for ^$n {
$tmp += @a[$_] * @b[$_];
}
return $tmp;
}
}
それから何でもそれを分類するdoes PDL_stuff[num] has an inner() (希望を抱いて)PDLを通しているエンジンに有用な形式にコンパイルされることができる関数。 多分同じくどこかに、翻訳されたコードから、安全なPDLシグネチャーが手続き上でその情報を隠す離れているストアがコードするマクロ。 もしかすると若干[n] 缶がとしてシグネチャーの中に戻って来る情報where 型の上の制約。
これは多分異なった制約で同様にタイプされた配列に多メソッドディスパッチを可能にするだろう。
(Perl 5 のPDLの特別な破壊問題は実行時システムで正確にPDLのオブジェクトが登録されているのと同じぐらい長い Perl 6 の GC アプローチで消え失せるべきだ。)
ジャンクションがそうであるデータについて一つのデータ値であるふりをしている値を最大に置く. ジャンクションが4つの多種多様さで来る:
list op infix op ======= ======== any() | all() & one() ^ none() (no "nor" op defined)
インフィックスオペが「リスト - 結合性」であるとは、注意する限りにおいて
$a | $b | $c $a & $b & $c $a ^ $b ^ $c
平均
any($a,$b,$c) all($a,$b,$c) one($a,$b,$c)
よりむしろ
any(any($a,$b),$c) all(all($a,$b),$c) one(one($a,$b),$c)
ジャンクションを取り扱うことに対して、ブールのコンテキストのような、若干のコンテキストが特殊なルールを持っている。 何でも値のジャンクション、ジャンクションを期待しない項目コンテキストがアルゴリズムの自動的な平行化を産み出す。
特に、もしジャンクションがルーチン(演算子、クロージャ、メソッドなど)とあなたが引数をバインドしようと試みているスカラーパラメータがそれと一致しない何への引数としてでも使用されるならJunction 型、そのルーチンは、自動的に多くとして時必要に応じてルーチンが呼び出されるであろう、からプロセス、ジャンクションの個別のスカラー要素、は並列にであることを意味して、「自動的にスレッドされる」。
(Each 型が同じく自動的に通される、しかし本質的に連続的で、そしていい加減だ。)
これらの別個の呼び出しの結果はそれから、 junctive 引数と同じ種の一つのジャンクションの中に改造される。 もし2かそれ以上の引数が junctive であるなら、「自動的に通される」ように選ばれる引数はそうだ:
左端すべてあるいはゼロのジャンクション(もし何も)、排他的論理和
左端の(の・もの・人)あるいはどんなジャンクションでも
テストが応用であるという状態で、そのオーダーで。
(これ・それ)以上の junctive 引数が残留しないようになるまで、呼び出しの結果として生じているセットのそれぞれがそれから回帰的に自動的に通される。 すなわち、:
substr("camel", 0|1, 2&3)
-> all( substr("camel", 0|1, 2), # autothread the conjunctive arg
substr("camel", 0|1, 3)
)
-> all( any( substr("camel", 0, 2), # autothread the disjunctive arg
substr("camel", 1, 2),
),
any( substr("camel", 0, 3), # autothread the disjunctive arg
substr("camel", 1, 3),
)
)
-> all( any( "ca", # evaluate
"am",
),
any( "cam",
"ame",
)
-> ("ca"|"am") & ("cam"|"ame") # recombine results in junctions
個々に引き抜かれて、そしてスカラーとして使用されないなら、ジャンクションがコンテナの一部が自動的に通すことを引き起こさないように、パスした。 「素晴らしい」配列あるいはハッシュのメンバーがそのパラメータの上に自動的に通すことを引き起こさないように、ジャンクションがパスしたことは続く。 ただ個々にパラメータがそうするかもしれないと宣言する自動装填. (けれども、位置の配列とハッシュパラメータが実際スカラーパラメータであるとは、注意しろ、それであなたは配列あるいはハッシュオブジェクトのジャンクションをパスすることができた。)
長い間に変更を受け得るコントロールに関して構造がそうである自動的にスレッドすることの正確な意味規則は;標準の一つのディスパッチあるいは関数呼び出しとしてとしてではないが実装したどんなコントロール構造にでもジャンクションをパスすることがそのために誤っている。 特に、正確にジャンクションを条件付きに通すことはほとんど、しかし完全にではなく Perl 6.0.0で義務化される継続を伴うことができた。 代わる代わる、我々は利用可能な「真の」ではないに崩壊を許したデフォルトと正確な値までにブールのコンテキストが常にジャンクションをつぶすと決定するかもしれない。 それの変形が、もしあなたがコントロール構造を自動的に通すことを欲するなら、あなたが - 割り当てるか、あるいは非にバインドしなくちゃならないと伝えるはずだMu コントロール構造とその割り当ての前のあるいは何にでもこのようなコンテナをバインドするコンテナがダイナミックスコープの残りを自動的に通すという結果をもたらす。 (しかしながら、これのパフォーマンスの波及効果はそれ以上の実験なしで明確じゃない。) それで今のところ、どうかジャンクションの使用をスカラー仮引数への終局のバインディングが明確である状況に制限してくれ。
[このセクションは推測であると見なされる。]
Each ジャンクションのような型自動スレッドが、けれども、連続的に、そしていい加減にそうして、そしてそのマッピング能力のためにだけ使われる。 典型的な使用ケースは不運な方法で超演算子が parallelize するであろうところだ:
@array».say # order not guaranteed @array.each.say # order guaranteed
スコープの中のuse autoindex プラグマ(あるいは匹敵するもの、そんなものけれどもuse PDL (多分))、パラメータを添え字として使うクロージャが自動的にスレッドして同じく賛成の候補者である何も. おのおののそのようなパラメータのために、コンパイラはデフォルトに(「可能な」が形づくられた配列の宣言された形、あるいは配列を自動的に拡張することの実際の形を意味するためにとられる)添え字が雇うことができるすべての可能な値のレンジである値を与える。 すなわち、もしあなたが形式のクロージャを持っているなら:
-> $x, $y { @foo[$x;$y] }
それからコンパイラはあなたのためにデフォルトを加える、何かが好む:
-> $x = @foo.shape[0].range,
$y = @foo.shape[1].range { @foo[$x;$y] }
おのおののそのようなレンジがあなたのために自動的に反復されるところ。
抽象的に(そしてしばしばコンクリートで)、これはその次元の間(パラメータが、クロージャに、実際に供給される、その場合供給された値がその代わりにスライス添え字として使用されない限り)暗黙のループをすべてを訪問するクロージャ、可能な添え字値、のブロックの周りに置く。
この暗黙のループは parallelizable だと考えられる。
それで典型的な張筋掛け算を書くために:
Cijkl = Aij * Bkl
あなたはただ、許して、引数なしでクロージャを呼び出すことができるautoindex
デフォルトを記入するプラグマ:
use autoindex;
-> $i, $j, $k, $l { @c[$i; $j; $k; $l] = @a[$i; $j] * @b[$k; $l] }();
あるいはあなたは使うことができるdo BLOCK 同じく暗黙のうちに反復するそのクロージャを呼び出す構文(S04 で「do-once ループ」を見ろ):
use autoindex;
do -> $i, $j, $k, $l {
@c[$i; $j; $k; $l] = @a[$i; $j] * @b[$k; $l]
}
あるいは引数リストの代わりの使用プレースホルダー変数さえ:
use autoindex;
do { @c[$^i; $^j; $^k; $^l] = @a[$^i; $^j] * @b[$^k; $^l] };
それはほとんどきれいだ。
自由にされたパラメータが異なって多数の存在する配列添え字とマッチすることは誤っている。 (作られている配列が数えない。)
あなたたちが $i 、お金j、kドルあるいはlドルについて明示的に何にでもパスするか、あるいはそれらに前もって包帯をすることができた重要性.assuming メソッド、ただ自由にされたパラメータだけがどちらを自動的に通すかについて。
もしあなたが自由にされた配列パラメータをセミコロンリスト補間回路として使うなら(としてprefix:<||> 演算子)、それそのパラメータが使われるところはどこにでも同じこととマッチするに違いない添え字のワイルドカードリストとしての関数.
例えば、
do -> @wild { @b[ ||@wild.reverse ] = @a[ ||@wild ] };
次元数にかかわらず反転させられた次元で配列を生産すの@a.
オプティマイザは、もちろん、離れて最適化することが自由だ、それがそうすることができる暗黙が輪にする何かがどのように意味規則を変えることをいっそう効率的にしないで済ますべきか理解する。
(そこ(に・で)提案された構文がどちらかと言うと異なっているけれども)自動的にスレッドしてもっと多くのどのように使うべきかについての考えのために RFC 207を見ろ。
配列のように、あなたは多数の次元でハッシュを指定することができる、そしてキーのセットを修理した:
my num %hash{<a b c d e f>}; # Only valid keys are 'a'..'f'
my num %hash{'a'..'f'}; # Same thing
my %rainfall{ Months; 1..31 } # Keys: Jan..Dec ; 1..31
配列と異なり、あなたは同じく型、それからそれがその次元を入力するようにその型のすべての値に許す non- enumerated としてのハッシュ次元を指定することができる:
my num %hash{<a b c d e f>; Str}; # 2nd dimension key may be any string
my num %hash{'a'..'f'; Str}; # Same thing
my %rainfall{ Months; Int }; # Keys: Jan..Dec ; any integer
ただ文字列あるいは整数よりむしろキーとして何にでもオブジェクトを要することができるハッシュを宣言するために、何かを言え:
my %hash{Any};
my %hash{*};
不確定な次元数のハッシュがそうだ:
my %hash{**};
権限:制限、特定の型のオブジェクトへのキー:
my Fight %hash{Dog; Squirrel where {!.scared}};
標準的なハッシュ:
my %hash;
賛成で本当に短い:
my Mu %hash{Str};
キーが本質的に不変に違いない(とき・から・につれて・ように)、使われて何でもタイプすることに注意を払え、さもなくばそれは不変のキーとして機能するコピーを作ることが可能じゃなければならない、あるいはそれは copy-on-write 意味規則を持たなければならない。 それを削除して、そしてそれを元通りに差し込むことによって、以外ハッシュの中で重要なオブジェクトの値を変えることは誤っている。
オーダーはハッシュのキーについて実装に依存して、そして任意だ。
Unless %hash 方法で何ででも変えられる、そうするための連続した呼び出し.keys.kv.pairs.valuesあるいは.iterator 同じオーダーで要素にわたって反復するだろう。
デフォルトハッシュイテレータは呼び出されたプロパティだ.iterator それは取って代わられたユーザであり得る。 ハッシュがそれ自身イテレータを賛成であるという状態で必要とするとき.pairs.keys.valuesあるいは.kvそれ呼び出し%hash.iterator() 1(人・つ)を始めるために。 項目コンテキストで、.iterator イテレータオブジェクトを返す。
リストコンテキストで、それはイテレータによって入れられたいい加減なリストを返す。 ハッシュが、イテレータステートがいい加減なリストで記憶されるのと同じぐらい長くて、一度に1つのイテレータよりいっそう多くにいることは可能に違いない。
イテレータとしてのハッシュを自動的にソートさせることへの悪い面は、ハッシュが変化するとき、あなたが整列順序とリゾートですべてのキーを記憶するために、それを持っているであろうということだ。 代わる代わる、ハッシュ全体は ISAM 実装(含まれない(30、あるいはそれはそうであるべきか?)にタイされることができた).
なぜなら多次元のハッシュ、そのサイズがハッシュの宣言された次元の数であるハッシュイテレータがキーのリストであるという何によってでも返されたキー。 [30けれどもこれは値を見いだすためにもう1つのルックアップを暗示するように思われる。 多分関連づけられた値は同じくどうにかして中に束にされることができる。]
Autovivification は vivifiable パスが読み書きコンテナにバインドされる場合にだけ起きるだろう。 値抽出(すなわち、読み取り専用あるいはコピーコンテナへのバインディング)が autovivify ではなくする。
割り当てがバインディングと同じようにコピーコンテナでもてなされるとは、注意しろ、それでそれは同様その右側を autovivify しない。
中の展開式の Any 投稿Parcel バインディング時間に autovivification 決定を遅らせる。 (バインディングが区画パラメータに同じく決定を延期する。)
コードが非破壊テストのように見えるときでさえ、これは autovivification が意図するところなく起きることができた Perl 5 と反対だ:
# This is Perl 5 code
my %hash;
exists $hash{foo}{bar}; # creates $hash{foo} as an empty hash reference
Perl 6 にこれらの読み取り専用演算は本当に非破壊だ:
my %hash; %hash<foo><bar> :exists; # %hash is still empty
けれどもこれらのバインディングは autovivify をする:
my %hash;
my $val := %hash<foo><bar>;
my @array;
my $parcel = \@array[0][0]; # $parcel is a Parcel object - see S02
my :($obj) := $parcel; # @array[0][0] created here
my @array;
foo(@array[0][0]);
sub foo ($obj is rw) {...} # same thing, basically
my %hash;
%hash<foo><bar> = "foo"; # duh
この規則はそうする申請をするArrayHashそしてただ戻るよりむしろ autovivifiable 型オブジェクトを返す(S12 を見る)ことに決める他のいかなるコンテナ型でもFailure ルックアップが失敗するとき。 特に、 autovivification が失敗よりむしろ型オブジェクトに関して定義されるから、それが「死者を出した使用」の下でまだ機能することに注意を払え。
この表はいずれかのデータ構造に関しての演算が autivivify にこのようなオブジェクトに型オブジェクトをもたらすという直観力を固める:
operation autovivifies to
========= ===============
push, unshift, .[] Array
.{} Hash
autovivifying している上記のデータ構造のほかに++ そして-- 原因がそうするだろうInt 現われるために、~= 作るだろうStr など;これら以外上に機能する演算子の自然の帰結だFailure質的に、 autovivifying コンテナと異なっている。
成功したルックアップのために返されるであろう成功していないルックアップによって返された型オブジェクトの型が型とまったく同じであるべきだ。
唯一の相違はもうそれが公式にインスタンスを作られる(定義される)かどうかだ。
すなわち、あなたはそれらを区別することができないとして.WHAT あるいは.HOW, ただ via .defined.
autovivifiable 型について結び付いて、オブジェクトが非 writeable コンテナに型オブジェクトをその autovivifying クロージャがない類似の型オブジェクトに翻訳して、そしてその代わりに(関係がある歴史的な診断情報が振る舞った何ででも)コンテナの中にその新しい型にオブジェクトを発する。 魔法のようにバインディングの後の型オブジェクトを autovivify することができる読み取り専用パラメータについてそのためにあなたが呼び出すことができるマジカルなメソッドがない。 新たに境界変数がただ単純なイニシャライズされていない値であるように思われる. (それが読み書きコンテナにほかのところに再境界である場合に備えて、オリジナルの型オブジェクトはそのクロージャを維持する。)
若干の実装メモ:ネストされた autovivifications が、お互いの上に依存するネストされた型オブジェクトを作ることによって、機能する。 何もそれらの時間を測定するというコンテナが型オブジェクトを生産しなくちゃならないという一般的な場合でコンテナがどのようにバインドされるであろうか知らない。 これはいつが何かの中に遅れているバインディングを持っているキャプチャを補間挿入したかを含む:
\( 1, 2, %hash<foo><bar> ) # must defer \%hash<foo><bar> # must defer
しかしながら、特定の状況で、コンパイラは値がただ境界読み取り専用であることができるだけであることを知ることができる。 例えば、infix:<+> これが決して autovivify することができないように、プロトタイプを作られる:
%hash<foo><bar> + 42
このような場合、コンテナオブジェクトは決して呼び出されないであろう autovivifying クロージャを計算することについての苦しみを体験する必要がない。 他方:
%hash<foo><bar> += 42
それが autovivifies するように、変更可能なコンテナに左側をバインドする。
割り当てがバインディングのように見えない、しかしそれが本当にその内容を変えるために変更可能に違いないコンテナの上の数種類の原因となっているセットメソッドを呼び出していると見なせ。