Smalltalk での変数の使用法と違いを理解する助けが必要です。以下のコードの各変数の違いと使用法は何ですか?
Object subclass: #MyClass
instanceVariableNames: 'x'
classVariableNames: 'Yy'
poolDictionaries: ''
category: 'helpMe'
MyClass class
instanceVariableNames: 'zzz'
Smalltalk での変数の使用法と違いを理解する助けが必要です。以下のコードの各変数の違いと使用法は何ですか?
Object subclass: #MyClass
instanceVariableNames: 'x'
classVariableNames: 'Yy'
poolDictionaries: ''
category: 'helpMe'
MyClass class
instanceVariableNames: 'zzz'
変数は識別子です。変数は、何らかのオブジェクトへの参照を保持します。
instanceVariableNames : ここx
では、クラスのインスタンスに属します。
classVariableNames : ここYy
には、すべてのクラスのすべてのインスタンスで共有される変数のコピーがあり、静的変数にすることができます。そのため、x
異なるオブジェクト間で異なる値を持つことができます。ただし、Yy
値は 1 つしか持てません。
poolDictionaries : smallTalk で作成され、クラスのグループ間で共有される変数へのアクセスを提供します
カテゴリなしでクラスを作成した場合、カテゴリ 'helpme' は関連するクラスのコレクションです。クラスは空白のカテゴリで作成されます。
サブクラスには独自のinstanceVariableNames(zzz)があり、継承プロパティもあります。
非スモールトーカーの間の混乱を避けるために: あなたが入力したのは (Object クラスへの) メッセージで、'x ' および 'Yy' という名前のクラス変数。続いて、'zzz' という名前のクラス インスタンス変数 (クラス オブジェクト内のスロットであり、インスタンス内ではありません) を定義するために、作成したばかりのクラスへのメッセージが続きます。
グローバル変数
「Object」と「MyClass」は「グローバル変数」です。これらはどこにでも表示され、技術的にはグローバル ディクショナリ (キーと値のペアを保持) にバインドされます。古い実装では、そのような辞書は 1 つしかありませんでした。最近の実装では複数あり、それらは「名前空間」と呼ばれます。あなたの例では、 Object クラスに送信されるクラス定義メッセージは、「MyClass」という名前の新しいバインディングを作成します。
クラス変数
'Yy' はクラス変数です。これはバインディングも参照しますが、そのバインディングは、クラス メソッドとインスタンス メソッドの両方に対して、クラスとそのサブクラス内でのみ表示されます (以下を参照)。すべてが同じバインディングを参照しているため、サブクラスは同じ値を参照します。それらはサブクラスで再定義できますが、再定義するサブクラスのすべてのサブクラスは同じバインディングを参照します。
インスタンス変数
これらはオブジェクトのプライベート スロットです。「x」はあなたの例の1つです。オブジェクトとメソッド (操作) のレイアウトはサブクラスに継承されますが、もちろん、個々のインスタンスには独自の値があります。インスタンス変数はインスタンスメソッドから見えます (もちろん)。
クラス インスタンス変数
は、クラス自体がオブジェクト (メタクラスのインスタンス) であるため、プライベート スロットを持つこともできます。技術的には、これらは単にクラス オブジェクトのインスタンス変数であり、クラス メソッドから参照できます。インスタンス変数と同様に、レイアウトとメソッドはサブクラスに継承されますが、各 (クラス) には独自の値があります。C++/Java の言語には対応する構造がないため、これはよく誤解されます (クラス メソッドは継承され、Smalltalk では再定義できるのに対し、他の言語の静的関数は再定義できないことに注意してください)。
プール変数 (共有プール)
は、クラス オブジェクトによって非グローバルに保持されるバインディングを参照するという点で、クラス変数に似ています。ただし、これらは多くの共同クラスで表示されます (別の言語での「友達」に似ています)。クラス定義メッセージでプールに名前を付けると、そのバインディングがクラスおよびインスタンス メソッドから見えるようになります。通常、これらは共有定数を定義するために使用されます。
他の変数の型 (コード例にはありません) は、メソッド ローカルとブロック ローカルです。これらは、現在のコンテキスト内のスロットを参照します。これは、技術的には、メソッドまたはブロック (ブロックが実際にクロージャーである場合は外部コンテキスト) のスタック フレーム (継続) です。
「カテゴリ」は単なるクラスの属性であり、上記の変数と混同しないでください。これは、ブラウザーでより適切に編成できるようにするためのタグと考えてください。この属性が格納される場所の詳細は、方言固有です。ほとんどの場合、辞書である別の (いわゆる「組織」) を使用します。ただし、少なくとも 1 つの方言 (ST/X) は、それをクラス オブジェクトのプライベート スロットとして保持します (実際には、ある意味では変数です)。