stanford-oval/wikipedia huggingface dataset:
Smalltalk
言語としてのSmalltalk > 準標準的な文法 > 継続

継続渡し形式を支援する機能として継続があり、PharoやGNU Smalltalkで使用できる。もっぱら反復の中断や、メソッド内の処理を飛ばすために使われる。継続の使用は次の様に記述する。
result := Continuation currentDo:
[ :break |

	aCondition1 ifTrue: [ break value: 1 ]. "aCondition1がtrueなら以降の処理を中断しresultに1を代入する。"
	aCondition2 ifTrue: [ break value: 2 ]. "aCondition2がtrueなら以降の処理を中断しresultに2を代入する。"

	3 "aCondition1, aCondition2両方trueならresultに3を代入する。"
].
言語としてのSmalltalk > 準標準的な文法 > 生成器

遅延評価を支援する機能として生成器があり、PharoやGNU Smalltalkで使用できる。生成器はCoroutineにも利用できる。生成器の使用は次の様に記述する。
stream := Generator on:
[ :each |
	each yield: 1.
	each yield: 2. "stream nextを1回呼ぶまで実行しない。"
	each yield: 3. "stream nextを2回呼ぶまで実行しない。"
].

stream next. "-> 1"
stream next. "-> 2"
stream next. "-> 3"
生成器を使って処理を作ることは多くないが、配列などを使用する際、間接的に使用していることが多い。
| readStream grater2 total |

readStream := #( 1 2 3 4 5 ) readStream. "#readStreamにより#select:を遅延実行する生成器が作られる。"
grater2 := ( ( readStream select: [ :each | 1 < each ] ) collect: [ :each | each * 2 ] ) reject: [ :each | 8 > each ].
total := grater2 inject: 0 into: [ :value :each | value + total ]. "#inject:into:でeachに代入するとき初めて#select:と#collect:と#reject:が実行される。"
言語としてのSmalltalk > ファイル用構文

Smalltalk のプログラムは基本的に中間言語としてイメージファイルの中に格納され、ソースコードの編集は Smalltalk のGUI環境から行われる。このため基本的にファイルという形で Smalltalk のソースコードやプログラムを目にすることはない。しかし、ソースコードの交換目的などでどうしても Smalltalk 環境外でソースコードを管理する必要がある場合に備えファイル用の構文が存在する。ファイル用の構文は次のようになる。
Object
	subclass:		#Example
	instanceVariableNames:	''
	classVariableNames:	''
	poolDictionaries:	''
	category:		'example'.

Example methodsFor: 'Instance Methods A' 
!
selectorA1
	"処理"
	^ 0.
!
selectorA2: anArgument
	"処理"
	^ 0.
!!

Example methodsFor: 'Instance Methods B'
!
selectorB1
	"処理"
	^ 0.
!
selectorB2: anArgument
	"処理"
	^ 0.
!!

Example class methodsFor: 'Class Methods' 
!
selector1
	"処理"
	^ 0.
!
selector2: anArgument
	"処理"
	^ 0.
!!
本来他の言語の様なブロックが存在しないため、ブロックとして「!」が使用される。クラスの登録は「!」の一組で囲まれる。メソッドはプロトコル毎に「 クラス名 methodsFor: 'プロトコル' ! 〜 !!」というブロックで囲まれる。一つのプロトコルには複数のメソッドを定義でき、メソッド同士は一個の「!」によって区切られる。
ちなみに、クラス登録は単なるメッセージ送信であり特別な文ではないため、登録用ブロック外にも次のように単純なメッセージ送信の記述に使用する事が出来る。
Example methodsFor: 'Instance Methods A' 
!
selector1
!!

'hello' displayNl.
'world' displayNl.

Example2 methodsFor: 'Instance Methods A' 
!
selector
!!
ファイル用構文で記述されたメソッドの登録は、可読性や記述性の面からメッセージ式からかけ離れた変則的な構文が使用される。しかし、この変則的な構文を用いなければメソッドを登録できないわけではなく、次のように通常のメッセージ式でメソッドを登録する事も出来る。
Example
	compile:
		'
		selectorC: anArgument
			^ 0.
		'
	classified: 'Instance Methods C'.
上記では、クラスオブジェクトExampleのプロトコルInstance Methods Cに対し、メソッドselectorCを登録している。
言語としてのSmalltalk > 委譲と継承

Smalltalk において、継承とは特殊な委譲に過ぎない。
Object
	subclass:		#Derived	"DerivedはObjectクラスから派生させる"
	instanceVariableNames:	''		"オブジェクトに所属する変数は定義しない"
	classVariableNames:	''		"クラスオブジェクトと共有する変数は定義しない"
	poolDictionaries:	''		"クラスに所属する変数は定義しない"
	category:		'example'.	"クラスの分類はexampleとする(今回の名前に意味はない)"
このため、例えば上記のクラスオブジェクトの生成では、Derived クラスオブジェクトの基底クラスオブジェクトとして Object を指定しているが、処理系によっては下記の様に #superclass: メッセージを送る事で、基底クラスに別のクラスオブジェクトを指定する事が出来る。
"superclass: NewBase. メッセージを送り基底クラスを NewBase に変更する事が出来る。"
Derived superclass: NewBase.
処理系により不可能な事もあるがクラスオブジェクトだけでなく、インスタンスオブジェクトから派生することも出来る。
"インスタンスオブジェクトの nil から派生した Derived クラスを Smalltalk 環境に登録する"
nil
	subclass:		#Derived
	instanceVariableNames:	''
	classVariableNames:	''
	poolDictionaries:	''
	category:		'example'.
なお通常、派生元の基本となるProtoObjectやObjectはnilから派生しており継承関係は再帰的に循環している。
言語としてのSmalltalk > メッセージ

Smalltalk において、メッセージ、セレクター、メソッドはそれぞれ別物である。C++ 系統の言語の様にオブジェクトに対しメッセージを送るという事は単なる比喩ではない。
あるオブジェクトに対し #hello というセレクターを使ったメッセージを送る事を考える。この時、Smalltalk においては hello というメソッドが必ず呼ばれる保証はない。例えば「hello」メッセージを受け取るオブジェクトが hello メソッドを実装していなければレシーバーに指定されたオブジェクトの doesNotUnderstand: メソッドが呼ばれる事になる。
なお、多くの Smalltalk の処理系では doesNotUnderstand: の引き数で得られたメッセージを返すだけのクラスが用意されている。例えば Smalltalk 環境のひとつである Pharo ではメッセージ作成用クラス MessageCatcher が用意されており次のようにメッセージを拾い、他のオブジェクトに渡すことが出来る。
message := MessageCatcher new show: 'text'. "「show: 'text'」がmessageに代入される。"
message sendTo: Transcript. "「Transcript show: 'text'」が実行される。"
また、セレクターとメソッドが独立していることを利用して一つのメソッドを複数のセレクターに結びつける事もできる。
"#onClick:を使ったメッセージをopen:メソッドに転送させる。"
FileEventHandler
	addSelector:	#onClick:
	withMethod:	FileEventHandler >> #open:.
→「メッセージ転送」も参照
メッセージにはセレクターと引き数が含まれている。このため受け取ったセレクターと引き数を編集する事も出来る。
message := MessageCatcher
	new
		bold: true
		text: 'example'.

message selector keywords keysAndValuesDo:
[ :key :each |
        Transcript
                show: each, ':=', ( message arguments at: key ) printString;
                cr.
].
"
以下が出力される。

bold:=true
text:=example
"
言語としてのSmalltalk > メッセージ > 型付け

プログラミング言語一般の概念として型検査をソースコードの翻訳時に実行するか、実行時に実行するかにより静的型付けと動的型付けという区分が存在するが、Smalltalkは、そのどちらでもなく型なし言語（英: untyped）に区分される。Smalltalk の場合、変数に対する操作は全てメッセージ送信であり、変数の種類(型)毎にできる操作は決まっていない。また、オブジェクトに対しメッセージを送った場合、そのオブジェクトがメッセージに対応するメソッドを持っていなくとも実行環境がエラーを発生させる事はない。メッセージに対応するメソッドが存在しない場合、例外を出すか無視するかは、クラスに実装されたメソッドの内容次第である。したがって Smalltalk には型付けの概念はない。例えば、Pharo の MessageCatcher は全てのメッセージを拾うため、どんなメッセージを与えられても例外が発生することはない。また、GNU Smalltalkではnilから派生したクラスのオブジェクトに存在しないメソッドに対するメッセージを送ると何も反応しない。ただし高速化のため後述の特殊セレクターを使用した場合実行時に型検査する処理系が多い。ちなみに Smalltalk は基本的に中間言語に翻訳され、翻訳時にエラーを発生させるため構文検査は静的である。
言語としてのSmalltalk > メッセージ > メッセージと制御構文

制御構文の節で述べた通り、Smalltalkの殆どの制御構文はメッセージ式である。Smalltalkに明るくないプログラマーからは言い方や見方を変えただけと捉えられがちである。Smalltalkの制御構文は実際にメッセージであるがゆえに究極には制御構文の構文要素を次のように変数に分解してしまうことが出来る。
変数に分解した分岐制御の例：
| then else message condition |

then := [ 1 ].
else := [ 2 ].

message := MessageCatcher
	new
		ifTrue:  then
		ifFalse: else.

condition := 2 = 2.
^ message sendTo: condition.
これらの変数に分解された構文要素は、どのクラスのオブジェクトで無いといけないという制限はない。送られたメッセージを処理することさえ出来ればあらゆるオブジェクトに置き換える事が出来る。
言語としてのSmalltalk > メッセージ > 特殊セレクター

Smalltalkでは高速化のためいくつかのメッセージを特別扱いする。これを特殊セレクター（英: special selector）という。
典型的な例は#ifTrue:ifFalse:である。下記のコードはでは「ifTrue: [5] ifFalse: [6]」を評価した時にメッセージが送られる訳ではなく、バイトコードレベルでインライン展開され飛越し命令の表現に置き換えられる。このため実際にifTrue:ifFalse: という名のメソッドが呼ばれることもない。また、trueやfalse以外に上記のようなBoolean用のメッセージを送ると処理系によってはMustBeBoolean例外を発生させる。このように頻繁に使用する分岐や反復を特別扱いすることで性能低下を防いでいる。
3 < 4 ifTrue: [ 5 ] ifFalse: [ 6 ].
セレクターと名がつくが特殊セレクターは、特別扱いする条件が引数の状態を含んでおり、たとえ同じセレクターを使ったメッセージでも引数が条件に一致しなければ特別扱いしない。例えば下記のように引数に直接ブロックを指定していない場合では多くの処理系(VisualWorks, GNU Smalltalk等)は特別扱いせずメッセージ送信を実行する。
| then else |
then := [ 5 ].
else := [ 6 ].
true ifTrue: then ifFalse: else.
特殊セレクターはあくまで高速化の手段であるため種類は処理系によって異る。どの処理系が何を特殊セレクターとして扱うかは処理系ごとに提供される説明資料に記述されている。
またPharoのように設定から特殊セレクターを通常のメッセージ送信に切り替えられる処理系も存在する。
言語としてのSmalltalk > クラスオブジェクトとMetaclass

クラスオブジェクトもオブジェクトであるため、所属するクラスが存在している。クラスオブジェクトが所属するクラスはMetaclassというクラスのインスタンスオブジェクトである。
ByteString.                   "-> ByteString"
ByteString class.             "-> ByteString class"
ByteString class class.       "-> Metaclass"
Metaclassも当然ながらクラスに所属しており、再帰的にMetaclassに属するようになっている。
' ' class.                               "-> ByteString"
' ' class class.                         "-> ByteString class"
' ' class class class.                   "-> Metaclass"
' ' class class class class.             "-> Metaclass class"
' ' class class class class class.       "-> Metaclass"
' ' class class class class class class. "-> Metaclass class"
クラスオブジェクトが所属するMetaclassのインスタンスオブジェクトは特殊なオブジェクトであり、クラスの継承階層と同様に継承階層を持っている。
Collection  class superclass. "-> Object class"
Object      class superclass. "-> ProtoObject class"
ProtoObject class superclass. "-> Class"
クラスオブジェクトはMetaclassから生成された単なるオブジェクトで有ることから、Smalltalkが標準で提供するクラスオブジェクトとは異なる独自の構造をもったクラスオブジェクトを作ることができる。
例えば以下のようにメソッドの代わりにブロックを持つ無名クラスを作成することも出来る。
| class object |

"Metaclassからクラスオブジェクトを生成"
class :=
	Class 
		new
			superclass: Object;
			methodDictionary: MethodDictionary new.

"生成したクラスオブジェクトのセレクターにメソッドではなくブロックを紐付け"
class
	methodDictionary
		add:	#something1: -> [ :value | value ] block;
		add:	#something2 -> [ 2 ] block.

"生成したクラスオブジェクトをインスタンスオブジェクトの生成に使用"
object := class new.

Transcript
	show: ( object something1: 1 ) printString;
	nl.

"生成したクラスオブジェクトを基底クラスとして使用"
class
	subclass:		#Example
	instanceVariableNames:	''
	classVariableNames:	''
	poolDictionaries:	''
	category:		''.
言語としてのSmalltalk > 定数とオブジェクト

文法の節で述べた通りSmallatalkでは定数も全てオブジェクトである。どんな定数であれ#classや#inspectといった基本的なセレクターを使ったメッセージを受け取ることが出来るため、基本的な操作であれば定数と他のオブジェクトを区別する必要はない。
| showClass |

showClass :=
[ :object |
	Transcript
		show: object class name;
		cr.
].

showClass
	value: Object new; "-> Object"
	value: Object;     "-> Object class"
	value: nil;        "-> UndefinedObject"
	value: 0;          "-> SmallInteger"
	value: 0.0;        "-> Float"
	value: 0.0e1;      "-> Float"
	value: $0;         "-> Character"
	value: '';         "-> ByteString"
	value: #a;         "-> ByteSymbol"
	value: #'a';       "-> ByteSymbol"
	value: #();        "-> Array"
	value: [].         "-> BlockClosure"
言語としてのSmalltalk > 可変長オブジェクト

Smalltalk は、任意の広さで確保した領域を持つ可変長オブジェクトを作ることが出来る。Smalltalkには配列を表わすためArray等が存在するが、これらのクラスオブジェクトは可変長オブジェクトを使って構築されている。可変長オブジェクトの領域は、オブジェクトの生成したときの一度だけしか広さを指定できない。また、クラスオブジェクトの登録時にvariable〜で始まるセレクターを使っている必要がある。
Object
	variableSubclass:	#ExampleArray
	instanceVariableNames:	''
	classVariableNames:	''
	poolDictionaries:	''
	category:		'example'.

| array |

array := ExampleArray new: 100.	"要素100個分の領域を確保した可変長オブジェクトを生成する。"
array at: 1 put: 0.		"1番目の要素に0を入れる。"
array at: 1.			"1番目の要素を取り出す。"
言語としてのSmalltalk > 記憶領域の管理

Smalltalk は、ハンドルとごみ回収機能(ガーベッジコレクター)の全面的な導入によりハンドルテーブルの書き換えを利用した特殊な制御を提供している。
言語としてのSmalltalk > 記憶領域の管理 > ハンドルテーブルの書き換え

ハンドルが参照している記憶領域上のテーブルを書き換えることによりSmalltalkは、あるオブジェクトを参照している全ハンドルの参照先を一気に変更することができる。ハンドルテーブルの書き換えには#become:を用いる。ただし、数字や文字列といった定数オブジェクトは置き換えることはできず、定数を置き換える際は定数を保持しているオブジェクトを置き換える必要がある。
| value1 value2 |

value1 := 'hello' asValue.
value2 := value1. "この時点ではvalue2はValueHolder('hello')"
value1 become: 'こんにちは' asValue. "この時点でvalue2はValueHolder('こんにちは')になる"
#become:を使っている良い例はクラスオブジェクトの再登録である。Smalltalkではクラスオブジェクトはインスタンスオブジェクトが生きている間でも再登録可能でなければならず、インスタンスオブジェクトを生きたままクラスオブジェクトを再登録するために使われている。
言語としてのSmalltalk > 記憶領域の管理 > 弱参照

弱参照は参照カウント方式を使う言語でよくライブラリーとして実装されるがSmalltalkではハンドルの制御を用いた言語機能として用意されており相互参照しているが不要になっているオブジェクトを迅速に解放するために使われている。弱参照には#makeWeakを用い、#makeWeakを受け取ったオブジェクトは弱参照となる。
| holder object |
holder := ValueHolder new.
holder makeWeak. "holderが弱参照になる。"
object := Object new.
holder value: object.
ObjectMemory compact. "ごみ回収。この時点ではholder valueはnilではない。" 
object := nil.  
ObjectMemory compact. "ごみ回収。この時点でholder valueはnilとなる。"
言語としてのSmalltalk > 記憶領域の管理 > カゲロウ(蜉蝣)

カゲロウ(Ephemeron)は、どこからも参照されなくなった連想配列の要素を解放するために導入された記憶領域の管理機構でありSmalltalkで初めて実装された。例えば連想配列の添字として#keyがあったとして、#keyが連想配列以外の変数で参照されていなければ連想配列の要素は必要ない。このように不要となった要素を解放するために用いる。オブジェクトをカゲロウ状態にするには#makeEphemeronを用いる。
| association key |
key := Object new.
association :=
	Association
		key: key
		value: Object new.
association makeEphemeron. "associationがカゲロウになる。"
ObjectMemory compact. "ごみ回収。この時点ではassociation keyとassociation valueは共にnilではない。" 
key := nil.
ObjectMemory compact. "ごみ回収。この時点ではassociation keyとassociation valueは共にnilとなる。"
ここでは連想配列の要素としてよく使われるAssociationを例としているが、カゲロウが消滅する基準は最初のインスタンス変数でクラスに依存しないためどんなクラスでもカゲロウにすることができる。
言語としてのSmalltalk > Smalltalk の慣習 > 大文字からはじめる識別子と小文字からはじめる識別子 > 変数名

変数を表す識別子については、1文字目に大文字と小文字のどちらを使うか、大域変数か否かを基準にして決めることが慣習になっている。
環境自体も大文字小文字の使い分けを認識しておりメソッドを翻訳する際小文字の変数は局所変数かメンバーとして定義していないと、警告が発生したり翻訳失敗になる。
| --- | --- |
大域変数: 大文字からはじめる
大域変数以外(局所変数等): 小文字からはじめる
クラス名が大文字から始まるのは、クラス名が大域変数だからである。
よく使われるクラス以外の大域変数:
Smalltalk
Processor
Transcript
言語としてのSmalltalk > Smalltalk の慣習 > 大文字からはじめる識別子と小文字からはじめる識別子 > セレクター

セレクターを表す識別子については、基本的に1文字目に小文字を使うが、メソッドが存在するセレクターを避けたい場合は大文字を使う事が慣習になっている。
GNU SmalltakやVisualWorksで用意されている名前空間は、大文字のセレクターを使う典型的な例である。
Smalltalk SystemExceptions InvalidValue signalOn: 0. "「Smalltalk」以外は全てセレクター"
なお、名前空間が使える環境の多くは、翻訳時に名前空間の名前解決できる「.」区切りの拡張構文が用意されており、実際にはこちらの構文が使われることが多いため、セレクターを使った名前空間の指定を見る機会は少ない。
言語としてのSmalltalk > Smalltalk の慣習 > オブジェクトの生成と初期化

オブジェクトの生成には #new セレクターを使ったメッセージを使う。他の言語と違い、new は演算子ではない。
|object|

object := Example new. "Exampleクラスオブジェクトに「new」メッセージを送りオブジェクトを生成。"
Smalltalk ではクラスオブジェクトのメソッドもインスタンスオブジェクトのメソッドと同様に派生クラスによる再定義が可能である。このため new メソッドを再定義し初期化処理を記載する事が出来る。new メソッドを再定義してしまうとオブジェクトの生成自体が不可能になるように思われるが、本来 new メソッドは #basicNew セレクターを使ったメッセージをBehavior に送ってオブジェクトを生成しているためオブジェクトの生成手段がなくなるわけではない。このため new メソッドを再定義しても 「basicNew」メッセージをBehaviorに送ることでインスタンスオブジェクト生成することが出来る。
ただし、実際の初期化に new メソッドが使われる事は多くない。実際には慣習としてクラスの作者が新たに登録したインスタンス・クリエイションと呼ばれる new とは別の初期化用メソッドが使用される。インスタンス・クリエイションは一般的なクラスオブジェクトのメソッドであり、そのメソッドの内部で 「new」メッセージやその他のインスタンス・クリエイションを使って初期化済みのオブジェクトを生成する役割を持っているだけで基本的にその他のメソッドと変わらない。一般的にinstance creationというプロトコルに登録される。
| number |

number := Number readFrom: '10'. "readFrom:がインスタンス・クリエイション".
Smalltalk では1個のセレクターに対し1個のオブジェクトから複数のメソッドを関連付けられないため 「new」メッセージの送信によりできる初期化は1個のオブジェクトにつき一通りの初期化だけである。このため複数のインスタンス・クリエイションを用意することで用途に応じた複数の初期化方法を提供しているのである。インスタンス・クリエイションは一般的なメソッドのひとつでしかない。このためインスタンス・クリエイション持つクラスオブジェクトはアブストラクト・ファクトリーとして機能する。
具体的には次のように使われる。
defaultDatabase
	"既定のデータベースのクラスオブジェクトを定義した派生クラスで再定義可能なメソッド。
	 オーバーライドされた際は、必ずしもクラスオブジェクトが返されるとは限らず、インスタンス
	 オブジェクトが返される場合もある。"
	^ PostgreSQL.
database
	"databaseへの接続を返すメソッド。
	 defaultDatabaseにより返されたPostgreSQLに対し、インスタンス・クリエイションである
	 #connect:セレクターを使ったメッセージが送られ、PostgreSQLのインスタンスオブジェクトが生成される。
	 ただし、defaultDatabaseは、派生クラスによって再定義できるため、#connect:セレクターを使ったメッセージが
	 必ずしもPostgreSQLクラスオブジェクトに送られるとは限らない。"
	^ self defaultDatabase connect: self configuration.
また、Smalltalk はクラスメソッドを上書きできるため、インスタンス・クリエイションを次の様に実装する事で基本的な初期化処理を派生元のクラスに任せることができる。
x: aX y: aY
	^ self new
		x: aX;
		y: aY.
上記は、2次元座標用のクラスオブジェクトのインスタンスオブジェクトを初期化する派生元のクラスオブジェクトに実装されたインスタンス・クリエイションである。このクラスオブジェクトを継承した2次元座標用のクラスオブジェクトでは#x:y:セレクターを使ったメッセージに対応するメソッドを実装する必要はない。インスタンス・クリエイションを利用したパターンは Smalltalk では広く利用され、いたる所で見ることが出来る。
言語としてのSmalltalk > Smalltalk の慣習 > アクセッサー

Smalltalk では、単一の値を出し入れするメッセージの事を特にアクセッサ―と呼ぶ。引き数の有無により値の入出の方向を区別する。
例：
| コード | 意味 |
| --- | --- |
object value.: オブジェクトから値を取得する
object value: 10.: オブジェクトに値を渡す
Smalltalk においてアクセッサーはその他のメソッドと役割に違いはなく特別な意味を持たないが、プロトコルとして明示的に accessing（）として登録される点が特徴的である。
Smalltalk においてアクセッサーはインスタンス変数の出し入れや、クラス変数の単純な出し入れに使用される事は多くない。Smalltalk においてアクセッサーは次の用途でよく使われる。
| 目的 | 詳細 |
| --- | --- |
インスタンス変数やクラス変数の初期化: インスタンス変数やクラス変数からの値の取得時にインスタンス変数やクラス変数が nil であればそれらの変数を初期化する。
使用するクラス・オブジェクトの抽象化: クラス・オブジェクトあるいはファクトリーオブジェクトを取得できるアクセッサ―を用意し、アクセッサ―を派生クラスでオーバーライドする事で派生クラスからオブジェクトの生成に使うクラス・オブジェクトを自由に切り替えられるようにする。
保管場所の抽象化: オブジェクトが、インスタンス・クラス・プールのどこで管理されているかを抽象化する意味がある。例えばクラス変数やプール辞書の操作では、クラス変数やプール辞書の操作目的であってもインスタンスオブジェクトのメソッドとしてアクセッサーを用意する。
インスタンス変数やクラス変数に対する委譲: インスタンス変数やクラス変数に対しメッセージを送るアクセッサ―を定義し、複数の箇所でインスタンス変数やクラス変数に対する同じメッセージ送信をしないようにする。これによりself object value value: 1.というような複雑なメッセージをself value: 1.というメッセージに単純化する。
言語としてのSmalltalk > Smalltalk の慣習 > 定数

定数は、単に定数を返すアクセッサ―で定義する。C言語の影響を受けた言語のように定数を#defineや変数で定義するという慣習はない。
言語としてのSmalltalk > Smalltalk の慣習 > 附帯情報

Smalltalk では、非常に利用頻度の低いインスタンス変数やクラス変数を管理する方法として附帯情報（英: property）というパターンが使用される。附帯情報はインスタンス変数やクラス変数などの内部変数の代わりに連想配列によりオブジェクトを保持する仕組みである。
附帯情報の使用例：
Tag methodsFor: 'accessing'
!
id
	^ self valueOfProperty: #id.
!
id: aString
	self setProperty: #id toValue: aString.
!!
附帯情報が有効な身近な例としてはXMLやHTMLのタグ属性が挙げられる。例えばHTMLの id 属性や onClick といったイベント属性は、必ずしも全てのタグで使用されることはない。特にイベント属性については一つのHTML上に一切記述されない事もよくある。この様な使用頻度の低い属性のためにオブジェクトに一個一個変数を定義するのは記憶領域の無駄である。ましてや onClick、onMouseDown、onMouseUp等大量に属性があればこの無駄は馬鹿にならない。この様な無駄を省くために Smalltalk では附帯情報というパターンがよく使用される。
全てのインスタンス変数やクラス変数は原理的に全て附帯情報によって表現することが出来る。この点に着目しオブジェクトに所属する変数を全て附帯情報に置き換えた言語が後の Self であり、JavaScript である。これらの言語でオブジェクトに所属する変数をプロパティーと表現するのは、この Smalltalk における附帯情報(プロパティー)に由来するもので、附帯情報の仕組みの有無に関わらずインスタンス変数やクラス変数をプロパティーと表現するのは間違いである。
附帯情報は Self や JavaScript においては当たり前の様に使用されている。しかし、Smalltalk においては附帯情報を多用する事はデバックを著しく困難にするため不適切な作法とされており、HTMLの属性の様に本当に使用頻度の低い変数だけを附帯情報で扱い、常用する変数に附帯情報を乱用すべきではないと言われている。例えば変数は統合開発環境の機能で使用箇所を把握できるが附帯情報では使用箇所をアクセッサーに限定しない限り追跡不可能になる。また、附帯情報では変数の変化に反応するブレークポイントを仕掛けることも難しい。
言語としてのSmalltalk > Smalltalk の慣習 > 単純な例外処理

Smalltalk 以外の言語において、配列の範囲外にある配列要素の操作や、値の代入されていない連想配列の操作は、次の例のように操作の前に一旦判定を行なって例外処理するか、例外機構を利用する方法が一般的である。
| key |
key := #phoneNumber.
( map contain: key ) ifTrue: [ ^ map at: key ] ifFalse: [ ^ nil ].
一方 Smalltalk では、配列の範囲外操作の様に単純で頻発するような処理では、次のように予めメッセージに例外処理をブロックとして渡してしまう方法が一般的である。
"#phoneNumber に対応する値が無ければ常に nil を返す。map 自身に #phoneNumber が追加される事はない。"
^ map at:#phoneNumber ifAbsent: [ ^ nil ].
予め例外処理をメッセージに含めることで、単純な例外処理をより簡潔なものとしている。
この方法は、Smalltalk 独自の復帰文と組み合わせる事でより柔軟な制御をする事ができる。
次の処理は、連想配列に値が見つかればそれを表示し、値が無ければ何もしないという処理であるが、処理の中断の判定と連想配列からの値の取り出しを一度のメッセージ送信だけで実現している。
| value |

value := map at:#phoneNumber ifAbsent: [ ^ self ].
Transcript
	show: value;
	cr.
言語としてのSmalltalk > Smalltalk の慣習 > ブロックによる資源の開放

Smalltalkでは、ブロック内だけ資源を確保しブロックの終了後に資源を開放するというブロックによる資源の開放が行われる。ブロックによる資源の開放では、資源の確保と同時に資源の開放を強制できるため開放忘れや例外による開放漏れを防ぐことができる。C#のusingに類似するが、usingを書き忘れたままnewできない分さらに強力である。
"Pharo"
'example.txt' asFileReference writeStreamDo: "example.txtを開く"
[ :writeStream |

	writeStream nextPutAll: 'text'.

]. "example.txtを閉じる(例外発生時も閉じる)"
"GNU Smalltalk"
'example.txt' asFile withWriteStreamDo: "example.txtを開く"
[ :writeStream |

	writeStream nextPutAll: 'text'.

]. "example.txtを閉じる(例外発生時も閉じる)"
言語としてのSmalltalk > Smalltalk の慣習 > 要素の列挙

Smalltalk は反復処理のための基本構文を備えているが、ある値の生成器（入出力等）やある集合要素から要素を取得するときに基本的な反復構文を使う事は稀である。Smalltalk では、値を列挙するために値の生成器や集合要素に送るべきメッセージが概ね決まっており、値を取り出す際は極力、列挙メッセージ（英: enumerating）を使用する事が作法となっている。
次に列挙メッセージの送信例を示す。
配列に対する列挙メッセージの例：
#( 4 3 2 1 0 ) do:
[ :each |
	"配列の要素が1個ずつ each に代入され表示領域（Transcript）に表示される"
	Transcript
		show: each;
		cr.
].
実行結果:
4
3
2
1
0
数値に対する列挙メッセージの例：
( 0 to: 4 ) do:
[ :each |
	"配列の要素が1個ずつ each に代入され表示領域（Transcript）に表示される"
	Transcript
		show: each;
		cr.
].
実行結果:
0
1
2
3
4
列挙メッセージで使えるセレクターは #do: の様に全ての要素にブロックを適用するだけの単純なセレクターだけでなく、現在の集合要素の要素を操作した上で新しい集合要素を作成する #collect: や、集合要素から条件に一致する要素だけを抜き出し、新しい集合要素を作り出す #select:、集合要素の中から特定の要素を見つけ出す #detect:ifNone: など様々なセレクターがある。処理系によっては #groupBy:having: などSQLに類似したセレクターに対応するメソッドを多数用意しているものもある。Smalltalk では集合要素や値の生成器自体にこれらのメッセージを受け取れるよう実装する事で、集合要素のデータ構造や、生成器の入力元などの構造に依存せず最適な反復処理を実現できるようになっている。これらの列挙機能は近年の言語において foreach やyeild、LINQ等言語機能として賄われつつあるが Smalltalk においては、単にライブラリーの慣習として実現されている所が特徴的である。
言語としてのSmalltalk > Smalltalk の慣習 > オブジェクトの変換

Smalltalkでは一般的にオブジェクトに#as〜というセレクターを使ったメッセージが送られた場合、オブジェクトを別のクラスのオブジェクトに変換する。例えば次の様な変換がある。
Stringの変換による具体例(変換結果は処理系依存)：
'abcd' asSymbol.　　　　　　"→Symbolクラスのオブジェクト"
'10' asInteger.　　　　　　 "→SignedIntegerクラスのオブジェクト"
'10:00' asTime.　　　　　　 "→Timeクラスのオブジェクト"

"以下は処理系によっては存在しない"
'/home' asPath.　　　　　　 "→AbsolutePathクラスのオブジェクト"
'http://example.com' asUrl. "→Urlクラスのオブジェクト"
オブジェクトを別のオブジェクトに変換するメソッドやメンバー関数が用意されている事は、Smalltalkに限らず他の言語でも一般的であり珍しい事ではない。Smalltalkの慣習として特徴的なところは、既存のクラスにこのオブジェクトの変換をユーザーやライブラリーの作者が自由に組み込んでいる所である。例えばSmalltalkの処理系であるPharoでは、初期状態で基本的なクラスであるStringに54個ものas〜で始まるメソッドが定義されている。この大量の変換メソッドは、メソッド追加した際すぐに影響を判断できるためメソッド追加に対し寛容的なSmalltalk独特の空気を象徴している。しかし、既存のクラスにメソッドを追加すればライブラリーを併合した際、意図しない衝突を生むため多用は避けるべきであるとの意見も存在する。
オブジェクトの変換はただオブジェクトの内部表現の変換だけでなく情報の加工にも使われる。
オブジェクト変換による具体例：
#( 2 1 2 3 1 3 ) asSortedCollection asSet. "-> #( 1 2 3 )"
言語としてのSmalltalk > Smalltalk の慣習 > セレクターとオブジェクトを指定したイベント処理

イベントハンドラーを定義する方法として、Smalltalkでは次のようにセレクターと、レシーバーとなるオブジェクトを指定する方法が一般的である。
| view controller |
view := Morph new.
controller := FileControlHandler withOwnerView: view.

"#click:イベントが発生すると、controllerに対し#open:を使ったメッセージを送る。"
view
	handler
		on:	#click:
		send:	#open:
		to:	controller.
同様にイベントハンドラーを指定する別の方法としては、ブロックを指定する方法が考えられる。しかし、イベントハンドラーにブロックを使う方法は、セレクターとオブジェクトを指定する方法のようにinspectだけでブロックを抱えたオブジェクトがどんな処理を実行するか判断できないうえ、ほとんどの環境はブロックの直列化に対応しておらず直列化もできなくなってしまうため、Smalltalkの文化においては避けるべきとされる。
このセレクターとオブジェクトを指定したイベント処理の方法は、Objective-Cの文化にも引き継がれておりCocoa等のライブラリーにて頻繁に目にすることができる。
言語としてのSmalltalk > MVCとMVCから派生した設計方式

Model View Controller（MVC）は Smalltalk から生まれた、制御（コントローラー）と情報（モデル）、そして情報の表現方法（ビュー）の3つを分離しクラスオブジェクトの再利用性を高め、実行時に情報と表現の組み合わせを変更できるようにした設計方針である。Smalltalk の世界でMVCは更に表現を担当するクラスに既定の制御を取り込む仕組みを持たせることで PluggableMVC へと発展した。
言語としてのSmalltalk > MVCとMVCから派生した設計方式 > モデル支援機構

Smalltalk はクラスライブラリーの基礎部分からMVCやMVCから派生した設計方式で使用されるモデルの構築を支援する仕組みを持っており、Smalltalk 以外の言語と比べモデルの構築が格段に楽になっている。次にモデルの動作を確認する最低限のコードを示す。
モデルの登録:
"単純なモデルのクラスオブジェクトを登録"
Object
	subclass:		#ValueHolderModel
	instanceVariableNames:	'value'
	classVariableNames:	''
	poolDictionaries:	''
	category:		'Models'.

ValueHolderModel class methodsFor: 'accessing'
!
defaultValue
	^ 0.
!!

ValueHolderModel methodsFor: 'accessing'
!
value
	value isNull: [ model := self class defaultValue. ].
	^ value.
!
value: aValue
	value := aValue.
	self changed: #value.
!!
モデルの監視側登録
"モデルを監視する単純なクラスオブジェクトを登録"
Object
	subclass:		#ValueHolderObserver
	instanceVariableNames:	'model getSelector'
	classVariableNames:	''
	poolDictionaries:	''
	category:		'Models'.

ValueHolderObserver class methodsFor: 'accessing'
!
defaultModel
	"model が nil の場合に使用する既定のモデルを返す"
	^ ValueHolderModel.
!!

ValueHolderObserver methodsFor: 'accessing'
!
value
	model ifNil: [ ^ nil ].
	"modelから指定のセレクターで値を取り出す"
	^ model perform: getSelector.
!
getState: aGetSelector
	"モデルから値を取り出す際のセレクターはシンボルにより外部から指定する"
	getSelector := aGetSelector.
!
model
	"現在監視対象となっているモデルを返す"
	model isNull:
	[
		model := self class defaultModel new.
		model addDependent: self.
        ].
	^ model.
!
model: aModel
	"現在監視対象となっているモデルを監視対象から除去し、
	 aModelに指定されたオブジェクトを監視対象として追加する。"
	self model removeDependent: self.
	model := aModel.
	self model addDependent: self.

	"また、通常は新しいモデルからValueHolderObserverにとっての初期値の読み取りを行う。
	 ここでは、初期値の読み取りの代わりにモデルが持つvalueオブジェクトの内容を表示Window(Transcript)に表示する。"
	Transcript
		show: self value asString;
		cr.
!!

ValueHolderObserver methodsFor: 'updating'
!
update: anAspect
	"モデルが存在しないときは更新しない"
	model ifNil: [ ^ nil ].

	"モデルが更新されると呼び出され、モデルが持つvalueオブジェクトの内容を表示Window(Transcript)に表示する。"
	getSelector = anAspect ifTrue:
	[
		Transcript
			show: self value asString;
			cr.
	].
!!

ValueHolderObserver class methodsFor: 'instance creation'
!
on: aModel getState: aGetSelector
	^ self
		getState:	aGetSelector;
		model:		aModel.
!!
動作の確認：
| model observer |

model := ValueHolderModel new.

"監視対象にmodelを指定してobserverを生成。
 on:getState:内にてmodel valueが返す値、0が表示Window(Transcript)に表示される。"
observer := ValueHolderObserver
	on:		model
	getState:	#value.

"modelの値を更新。observerの#update:が実行されmodel valueが返す値、100が表示Window(Transcript)に表示される。"
model value: 100.
モデルの支援機構は全て Object クラスオブジェクトに実装されており、全てのオブジェクトはモデルとして動作する。つまりクラスオブジェクトもモデルとして使用できるようになっている。
言語としてのSmalltalk > MVCとMVCから派生した設計方式 > Morphic方式

PluggableMVC は Self へと場を移し、表現と制御そして、表現対象となる情報を1個のオブジェクトで兼任する Morphic（英語版） として再設計された。Self によって発展した Morphic は Smalltalk に移植されSqueak系統の Smalltalk 環境で基本GUIシステムを構築している。Self の Morphic はウェブブラウザ―のDOMや JavaScript に大きな影響を与えている。
Linux上で稼働するSmalltalk環境(VisualWorks)。
左上:Class Browser,
右上:Transcript,
左下:Workspace,
右中段:Debugger/Notifier,
中央下段:Inspector,
右下段:変数を表示したWorkspace
ガーラ湯沢駅

| ガーラ湯沢駅 |
| --- | --- |
 駅舎（2018年2月）
  がーらゆざわ  GALA Yuzawa  
 ◄越後湯沢 (1.8 km)
 ja
 新潟県南魚沼郡湯沢町大字湯沢1039-2北緯36度57分3.2秒 東経138度47分58.3秒﻿ / ﻿北緯36.950889度 東経138.799528度﻿ / 36.950889; 138.799528座標: 北緯36度57分3.2秒 東経138度47分58.3秒﻿ / ﻿北緯36.950889度 東経138.799528度﻿ / 36.950889; 138.799528
所属事業者:  東日本旅客鉄道（JR東日本）
所属路線:  ■上越新幹線 （正式には上越線支線）
キロ程:  1.8 km（越後湯沢起点） 東京から201.0 km
電報略号:  カラ
駅構造:  地上駅
ホーム:  1面2線
乗車人員 -統計年度-:  1,098人/日（降車客含まず） -2023年-
開業年月日:  1990年（平成2年）12月20日
備考:   臨時駅（冬季のみ営業）  みどりの窓口 有 
テンプレートを表示
ガーラ湯沢駅（ガーラゆざわえき）は、新潟県南魚沼郡湯沢町大字湯沢にある、東日本旅客鉄道（JR東日本）の駅である。JR東日本のグループ会社が経営するガーラ湯沢スキー場に直結している。
施設上は越後湯沢駅で分岐する上越新幹線の支線の終点に当たるが、越後湯沢 - ガーラ湯沢間は法規上、在来線である上越線の支線となっている（乗車券の扱いに関する詳細は後述）。
概要

JR東日本社員の発案による社内プロジェクトとして、上越新幹線の越後湯沢駅に隣接する保線基地の裏山に開業したガーラ湯沢スキー場への利用客の輸送のために「東京から75分で行けるスキー場」として開業した。そのため、冬季のスキーシーズン（概ね12月中旬 - 翌年5月上旬）のみの臨時駅となっている。当初計画ではスキー場名・駅名とも単に「ガーラ」となる予定だったが、地元からの強い要望で「湯沢」が付いた。
駅舎自体がガーラ湯沢スキー場への玄関口となっており、駅舎には「スキーセンター カワバンガ」の愛称が付与されている。エントランスがある1階には温泉施設「SPAガーラの湯」（入口は3階）、改札口がある2階にはチケットカウンターやスキー・スノーボードレンタルカウンターがある。スキー場へはゴンドラリフト「ディリジャンス」で結ばれているほか、スキー場北エリアからの下山コース「ファルコン」の終点でもある。なお、シーズン毎に駅舎内の大規模なリニューアルを行うことも多く、案内表示やカウンターも度々変更・更新されている。
開業の経緯から、駅としては基本的には冬季のみの営業だが、JR東日本がタイアップした映画『ジュブナイル』の関連イベント開催などで、夏季に営業を行ったケースが数回ある。営業を行っていない時期の越後湯沢駅 - 当駅間は、越後湯沢駅に発着する「たにがわ」の折返し用に使用されている。また、夜間停泊も行われている。同区間は信号システム上、単線並列になっている。
なお、夏季にはスキー場のサマーゲレンデ営業や、周辺でトレッキング企画が実施されるが、駅の営業や旅客列車の運行はなく、交通手段は越後湯沢駅からのシャトルバスもしくは自家用車、タクシーになる。また、冬季においても、午後にガーラ湯沢着となる列車が18時台着の1本しか設定されていないなど、列車の運行時間帯に偏りがあり、タイミングが合わない場合には越後湯沢駅からのシャトルバス利用が必要となる。
駅名及びスキー場名の「ガーラ (GALA) 」とは英語で「祝祭」を意味する。ガーラ湯沢スキー場も含めて「祝祭空間」であることを強調している。そのため、駅員の一部は制服・制帽もJR東日本の正規のものとは異なるものを着用している。