タートル操作や描画機能に、アラン・ケイの「メッセージング」というアイデアを組み合わせて作られたクラスベースで手続き型の純粋オブジェクト指向プログラミング言語、および、それによって記述構築された統合化プログラミング環境の呼称。Talk」「SmallTalk」などは誤りである。Project[2]があり、国産製品の開発実績としてはMCFrameがある。外部リンク概要[編集]開発の経緯[編集]ゼロックスのパロアルト研究所(PARC)で1970年代に約10年かけ3世代(Smalltalk-72、76、80)を経て整備された。ハードウェア技術を基にした商用マシン上で動作するプロの開発者向け統合化プログラミング環境「Smalltalk-80」として1983年に発売されることになる。VisualWorks(ビジュアルワークス)という製品名で主要なオペレーティングシステム向けに販売されている。Smalltalkの変遷[編集]※この節は[4][5]を元に執筆されている。最初にSmalltalkの名前を冠した言語だが、文法など一部仕様が定められただけで実装はされていない。メッセージングの機構により最初に動作したSmalltalk。初期のGUIはタートルグラフィックスで表現されたウインドウやメニューなど原始的な構成で、言語仕様的にもクラスが関数であったり、メソッド定義がリーダーマクロのようであったりと、現在のSmalltalkとは異なる点が多い。Smalltalk-72に対し、処理系の高速化、GUIの整備、オブジェクト指向仮想メモリー(OOZE)を導入したバージョン。現在のメッセージ式に近い文法(特にキーワードメッセージ式)を取り入れたSmalltalk。メタクラス、第一級オブジェクトとしてのブロックなどはまだない。Smalltalk-76を、可搬式の試作機「NoteTaker」で動作するよう8086向けにBitBlt等を再構築し、小さく整理したバージョン。現在に知られる仕様となったSmalltalk。Smalltalk-80を一般に普及させるために開発・販売されたSmalltalk。ObjectWorksを引き継ぎ開発されたSmalltalk。Smalltak直系の子孫で現代に至るSmalltalkの中で本家と言える存在である。v1(リリース前バージョン)を元に、XEROX社に許諾および指導を受けてアップルが開発したSmalltalk。同時期にDEC社、テクトロニクス社、ヒューレット・パッカード社でも同様の試みがなされている。Smalltalkを元に開発された。Smalltalkの設計者により開発されており、いわば分家と言える存在である。Squeakから派生した実装。大胆で実験的な機能追加の試みが多いが、2017年現在精力的かつ活発に開発が進められているSmalltalk処理系のひとつ。オブジェクト指向[編集]豊富で整備されたクラスライブラリーは、特にオブジェクト指向プログラミングの手本とされ、デザインパターンの宝庫と称されるまで洗練されたものになっている。後世の多くのオブジェクト指向プログラミング言語に直接間接的に多大な影響を与えた。システムが体現した「パーソナルコンピューティングに関わる全てを『オブジェクト』とそれらの間で交わされる『メッセージ送信』によって表現すること」を意味していた。設計を通じて整理し発表した「『継承』機構と『多態性』を付加した『抽象データ型』のスーパーセット」という考え方として広く認知されるようになった(カプセル化、継承、多態性)。現在は、両者の渾然一体化した曖昧な概念として語られることが多い。流れを強く受け継ぐ言語、およびその開発手法に慣れた開発者にとって極めてとっつきにくい言語・環境であるといわれている。単なるプログラミング言語ではなく、従来のオペレーティングシステムの概念をも包括する「環境」であることが一つの理由である。単なる言語としてとらえると、他の言語と比較したとき、使用するオペレーティングシステムのグラフィカルユーザインターフェースに全く従わないなど、その独自性が大きな「欠点」として映る場合もある。言語や処理系を学ぶなら、多かれ少なかれ新たなオペレーティングシステムに接するような心構えを持つべきことを意味する。ソースコードとして実行できるためシェルにコマンドを打ち込んだ時の様に簡単な問い合わせをすぐ実行できるようになっている。it(WindowsであればCtrl+Dを押す)すれば良い。言語のメッセージ式が使われる。現在設定されている値がメッセージ式として取得でき、値の設定をメッセージ式として指定する。環境の実行中に設定用のウィンドウから入力される。環境の実行方法として現実のハードウェアに依存している機械語命令を使わず、現実のハードウェアから独立した中間言語命令(仮想機械に対する機械語命令)を仮想機械により実行する仮想機械方式を採用している。言語仕様にも含まれている。導入したこの仮想機械方式はEULERのpコードマシンからアラン・ケイが着想を得たものである。環境の実行状態をそのまま保存したファイルである。環境の実行状態を保存している。中間言語も含まれている。自身によって記述されたコンパイラーによってソースコードから翻訳された、バイト列のオブジェクトである。用意する事はできない。初期段階ではALTOのアセンブリ言語によりコンパイラーや仮想機械が実装されていた。[8]実行時書き換え[編集]Smalltalk環境は翻訳方式を使う処理系としては珍しくプログラムの実行時書き換えを基本とする。Browserに入力したプログラムはソースコードを中間言語に変換したあとSmalltalk環境の一部として取り込まれ、環境を再起動したり読み込み操作をしなくても起動中のSmalltalk環境内で実行することができる。C++のような翻訳式の言語であれば原則、ソースコードを書き換えた場合は原則プログラムの再起動が必要となる。Pythonの様な言語ではソースコードを再読み込みする処理を予め書き換えたい処理の呼び出し元に組み込んでおかなければソースコードをいくら書き換えても動作に反映できない。Smalltalkではその再起動や再読み込み処理の組み込みが必要ない。このため環境をソースコードを書き換える都度環境全体を再起動しなくて済むのはもちろん、Windowを表示するプログラムを作った場合であれば、Window内のButtonの動作を変更する時もWindowを表示したままソースコードを書き換えて動作を変更できる。このためButtonを押すまでに複数の手順が必要なプログラムやWindowの表示に時間がかかるプログラムでもButtonを表示した状態から再起動せず何度でもやり直しができ効率的なソースコード変更が可能になっている。2017年現在VisualWorksを販売するCincomのWindows向け製品となっている。ゼロックス時代のSmalltalkを引き継ぐSmalltalk環境。名前空間[11]やイメージファイルからモジュールを切り離せるパーセル[12]、OSのデスクトップ上に表示できるウィンドウ等以前のSmalltalkより大きく拡張されている。2017年現在も活発に開発されている。Smalltalkから派生したプラットフォーム非依存やマルチメディア対応を強化したSmalltalk環境。Squeakから開発向けに派生したSmalltalk環境。データベース管理システムとしての用途に特化したSmalltalk環境。その用途からGUIは無い。systemにて無償版が配布されている。[2]2017年現在も活発に開発されている。GUI無しでの開発に特化しており他の環境ではGUIを前提としている機能をCUIで実行できる。GUI環境も用意されている。[3]Cと連携するための機能が他の処理系と比較して特に強力であり、関数のポインターを指定すべき引数にブロックを渡したり、関数呼出もできる各種ポインター操作ができるようになっている。関数のポインターとして渡すブロックは変数を束縛した状態で渡す事が可能になっている。言語仕様に静的型検査を追加したSmalltak環境。spotによる最適化を初めて実装したVMで極めて高速に動作する。Pharoの環境を元に言語仕様に静的型検査と動的型検査を追加したSmalltak環境。Browser上で動作するSmalltalk環境。Windowsに特化しておりOS固有の機能やOS固有のGUIを使用できる。OSとの親和性が高い。Smalltalkの名前を目にする機会が多い。Frameworkを使用する。Unixで動作するSmalltalk環境。pc98で動作するSmalltalk環境。Smalltalk/VからIBMが派生させて開発したSmalltalkベースの統合開発環境。Javaで記述されたEclipseの原型でもある。IBMが開発を停止したVisualAgeの派生製品。[22]2018年現在も開発が継続されている。Smalltalk環境として稼働する上で必要最低限の機能だけを備えるSmalltalk環境。アクターモデルによる分散処理を導入した環境。-GUIツール[編集]Linux上で稼働するSmalltalk環境(VisualWorks)。右下段:変数を表示したWorkspace準標準的なGUIツール[編集]GUIを使わないような特殊なものを除き、大半のSmalltalk環境では次のようなGUIツールが用意されている。Browser)TranscriptWorkspaceDebugger/NotifierInspectorSmalltalkの開発ではこれらのツールを使って開発する事が半ば前提となっている。Browser)[編集]Smalltalk環境内に存在する全てのクラスを(存在する場合は名前空間も)表示/編集できるツールで、Smalltalk開発において中核となるツールである。この節の加筆が望まれています。Transcript[編集]言うなれば出力しかできないコンソールといったツールで、プログラムの実行結果を簡易的に表示したいときに使われるツールである。Smalltalk環境内でTranscript変数に書き込まれたメッセージは、全てこのTranscriptに表示される。Workspace[編集]言うなればコンソールの入力側とテキストエディターを組み合わせた様なツールである。すれば書いたコードを実行できるだけの簡易的なテキストエディターにしか見えないが、WorkspaceはWorkspace変数というWorkspace固有の変数を持っており、Workspace内で実行されたSmalltalkコードの実行結果を保持することができる。このため、長いコードを書くような用途では使わず、Smalltalk環境に対するパッケージの追加や、環境設定、ファイルの一時的な操作など一時的な操作を実行する場所として使われる。Debugger/Notifier[編集]この節の加筆が望まれています。Inspector[編集]オブジェクトの内部構造を再帰的に表示するツールである。多くの場合オブジェクトの編集が可能でありWorkspaceと組み合わせてオブジェクトを組み立てていくことが可能である。画面部品をWindowを表すオブジェクトに組み込み、クラス変数に格納するといった具合である。Inspectorに限らずSmalltalk環境全体に共通することであるが、オブジェクト内の変数を表示するときは内部構造そのままではなくオブジェクトの文字列表現で表示する。)といった読み易い表示となる。それは計算機を計算機の集合体として構築し、さらに計算機を構成する個々の計算機も計算機の集合体で構築するというように、再帰的な計算機を構築することであった。この再帰的な計算機を構築している無数の計算機は、個々の内部には干渉せずメッセージによる通信のみによって相互作用を発生させ目的の計算を完遂させる。オブジェクトという形で実装された。この設計思想の誕生は、ロバート・S・バートン(英語版)とB5000の設計者らが会談した際の次の発言をアラン・ケイが聞き「計算機の全体を計算機とみなした場合、その計算機の構成要素を計算機に分解するのではなく関数やデータ構造に分解したいと誰が思うのか」と疑問を浮かべた事がきっかけとなっている。至るところに影響を与えている。反復はメソッドの再帰呼び出し。インスタンスオブジェクトを生成しているクラスオブジェクトも、クラスオブジェクトに所属するインスタンスオブジェクトであり再帰関係を持つ。classは、Metaclassであり再帰関係を持つ。基本的な派生元となるObjectやProtoObjectは、それらから派生したUndefinedObjectのインスタンスオブジェクトであるnilを継承しており再帰関係を持つ。言語自身によりメッセージ送信等の言語機能が制御される。言語により実装される。言語の大域変数はSmalltalk変数に格納されたオブジェクトにより管理されるが、Smalltalk変数自体も大域変数である。言語仕様は原則として非常に単純なため、環境もしくは処理系の相違による互換の有無は、クラスライブラリーの差異程度に由来するもの(ある意味、バージョンの違いもこれも含まれる)から、言語仕様自体の改変に由来のものまで空間的に連続で多岐にわたる。して語弊のある場合、一般にその環境および処理系の呼称もしくは商標(必要ならそのバージョン)をして他と区別するために用いる慣習がある。文法[編集]コメント[編集]「"~"」のようにダブルクオーテーションでくくった文字列がコメントとして扱われる。定数表現[編集]主な定数表現には次のようなものがある。]定数ではないが、よく用いられるオブジェクトの生成式には次のようなものがある。使用者も同様の機能を作ることが出来る。変数[編集]一時変数は宣言が必要で、「|」で挿むように記述する。変数への代入は「:=」。古い処理系では「_」が使用された(字形は「←」)。変数に型はなく全てハンドルになっている。実行中のコンテキスト(スタックフレーム)を参照するのに使える。その基底クラスである。「メッセージ式」と呼ばれる書式でコードを記述する。messageと記述する。メッセージはさらに、呼び出されるされるメソッド(処理手順)の名前を表す「メッセージセレクター」[25]と0個以上の引数の組み合わせからなる。場合必ずしもセレクターとメソッド名は一致しない。メッセージの送り先はメソッドではなくブロックや外部の関数になっている場合もある。セレクターは引数の数だけコロンを自身に含まなければならず、メッセージとして記述する際にはコロンの直後に引数を挿入する。arg1、arg2引数なしのメッセージを単項メッセージ、そのセレクターを単項セレクターと呼び、引数ありのメッセージをキーワードメッセージ、そのセレクターをキーワードセレクターと呼ぶ。secondArg:)をキーワードと呼ぶが、あくまで便宜的な呼び名に過ぎず、そうした言語要素は存在しない。他の言語に見られる「キーワード引数」のように省略できるものではなく、また引数順を入れ替えられるものでもない。セレクターは原則としてアルファベットと数字と0個以上(かつ、引数と同数)のコロンから成るが、例外として二項演算を模した記述が可能となるように記号のみから成る引数1つのセレクターを使ってメッセージ式を記述することもできる。これを二項メッセージ、そのセレクターを二項セレクターと呼ぶ。4」がメッセージである。通常の処理系では、単項メッセージ、二項メッセージ、キーワードメッセージの順で評価される。二項メッセージ間で乗除の優先はない。)セミコロン「;」でメッセージ式を区切る事により、1個のレシーバーに対して複数のメッセージを送ることが出来る。これをカスケード式という。4;yourself.カスケード式を用いて書いた上記の文は、カスケード式を用いない次の文と等価である。4.制御構文[編集]複数の式を順次実行する場合は、式をピリオドで区切る。言語機能として持つ制御構文は復帰文を除いて存在せず、復帰文以外の制御は制御構文と同等の機能を持ったメッセージ式で代用する。ブロック[編集]ブロックは、他の言語で言えば無名関数やクロージャーに該当する機能である。ブロックは関数ではなくオブジェクトである事に加え、無名関数というより制御構文としての性格が強くなっている。並列実行の基本単位にもなる。ブロックは、引き数の数毎に複数定義された「value」を含むメッセージを送る事で、ブロック内に記述されたメッセージ式を実行し結果を返す。:value2は引き数であり、「|」以降は「value」を含むメッセージが送られた際実行するメッセージ式である。)しか定義されておらず。5個以上引き数を取る場合は、配列を引き数とする#valueWithArguments:を使う必要がある。メソッドが値を返す際は、復帰文の記述が必要となるがブロックの場合は値を返すのに復帰文は必要ない。最後に実行されたメッセージ送信の結果あるいは、最後に書かれた値が戻り値となる。ブロックは制御の基本となるオブジェクトであるため、「value」を含むメソッド以外にも膨大なメソッドを持っている。後述する他の制御構文はブロックに対し#valueセレクターまたは、#value:セレクターを使ったメッセージしか送らない。ブロックにはvalueと合わせてよく使われるセレクターとして「cull」がある。cullの振る舞いは、ほぼvalueと同じであるが、ブロックがメッセージに含まれる引き数を無視できるという違いがある。1"cullはブロックによる分岐制御が主目的であるが、分岐の基準になったオブジェクトを参照する場合もあるようなセレクターで使われる。典型的な例は、オブジェクトがnilで無いときだけブロックを実行する#ifNotNil:である。セレクターを用いたメッセージ式として、条件式の結果の真偽値へのメッセージ送信の形で次のように記述する。専用の条件式も存在する。].条件分岐の制御において、他の言語でいうswitchに直接該当する文は存在しない。多態性を利用して分岐するか、次のように連想配列を利用して分岐するため不要である。|"速度が求められる場合は、初期化済みのDictionaryのオブジェクトをインスタンス変数やクラス変数にキャッシュする。value.但し一部の処理系では、次のようなswitchに類似した書き方ができるものも存在する。該当する文は存在しない。代わりに回数を指定した反復がある。回数を指定した反復は、整数型へのメッセージ送信の形で次の様に記述する。timesRepeat:["反復実行する処理"].現在の反復回数を参照しながら反復する事も出来る。該当する文は存在する。該当する反復は、ブロックに対するメッセージ送信の形で次の様に記述する。セレクターは、条件が真である間反復する事を意味している。いうセレクターも存在する。該当する文も存在する。該当する反復は、ブロックに対するメッセージ送信の形で次の様に記述する。条件なしの反復も存在する。無条件反復は、ブロックに対するメッセージ送信の形で次の様に記述する。反復方法が複数存在するが、実は全てメソッドの再帰呼び出しによって実装されているという事になっている。同様実際にメソッドの再帰呼び出しとして実行されていない事が多い。セレクターを使ったメッセージを送る。系セレクターに対応するメソッドが定義されており、他の言語には珍しい多様な反復の脱出方法を備えている。例外処理機構が存在する。こちらも、その他の構文と同じくメッセージ式とブロックによって実現されている。例外処理は次の様に記述する。|"例外を補足した際の処理"].なお#ensure:は後述のブロックによる資源の開放があるため多用されることはない。オブジェクトを操作し、コンテキストを巻き戻す事で実現されている。複数の例外は、#on:do:on:do・・とon:do:を繰り返し(処理系が定義している限りの数で)記述して補足する事もできるが、次の様に例外の型を,で並べて補足する事も出来る。|"エラーと通知両方の例外を1度に補足"].なお、Smalltalkでは正常な結果を返せないエラー(間違い)と通知両方を合わせたものが例外である。例外は正常な戻り値を返せない場合と割り込みの様に非同期な通知に利用される。並列処理[編集]Smalltalkでは、標準で並列処理が存在する。並列処理は次の様に記述する。resume."子処理の起動。"子処理の終了待機"並列処理はスレッドに類似するプロセスという仕組みにより実装されている。プロセスはSmalltalk環境内で構築された並列処理の仕組みであり、グリーンスレッドで実装されている事が多い。このため、プロセスは論理的に非プリエンプティブなスレッド(グリーンスレッド)を前提しており、現在実行している処理を切り替える切り替え点を必要とする。Smalltalkの様に実際はプリエンプティブなスレッドで実装されている場合もある。[26]プロセスは他のプロセスから割り込みとして任意の例外を投げる機能があり(記述方法は環境によって異なる)、切り替え点はプリエンプティブなスレッドを使う場合でも例外の発生地点として機能する。クラスの定義をメッセージ式による実行環境へのクラスオブジェクトの登録として実現する。他の言語と異なりクラスオブジェクトの登録は単なる定義ではなく実行環境に対する操作である。1度クラスオブジェクトを登録してイメージファイルを保存すると、明示的にクラスオブジェクトを削除しないかぎりはクラスオブジェクトがイメージファイルに残り続ける。環境に対するクラスオブジェクトの登録は次の様に記述する。派生した言語のクラス定義と概ね同じである。インスタンス変数はインスタンスメソッドのみから参照でき、クラス変数はクラスメソッドとインスタンスメソッドから参照できる。他の言語と異なりインスタンス変数をクラスメソッドから参照することはできない。おけるクラスの作成は、特殊構文ではなく単なるメッセージ送信である。クラスを登録する際のメッセージは、上記の例のように次のセレクターを使用することが多い。#subclass:instanceVariableNames:classVariableNames:poolDictionaries:category:しかし、クラスの登録はあくまでメッセージであり自由に作れるため、実行環境には大抵その他のメソッドが用意されている。次のセレクターに対応したメソッドが用意されている。クラスから派生したインスタンスとして状態を持つためのインスタンス変数がある。このクラスオブジェクトのインスタンス変数はクラスオブジェクト内だけで共有され、インスタンスオブジェクトからは直接使用できない。環境に対するクラスオブジェクトのインスタンス変数の登録は次の様に記述する。"クラスオブジェクトのインスタンス変数名(空白区切り)"クラスオブジェクトがもつインスタンス変数には変数を登録した基底クラスと派生クラスで別々の変数領域が確保されるという特筆すべき点がある。これを使用して下記の様にクラスに所属するオブジェクトだけを保持する変数としてつかったりする事ができる。0"メソッドの登録[編集]メソッド(処理方法)の登録は、コード文字列を引数として与えたクラスへのメッセージ送信でも行えるが、通常は環境に組み込まれたクラスブラウザ(システムブラウザ)と呼ばれるGUIツールを用いる。メソッドは、「メッセージパターン」と呼ばれるメッセージ式のメッセージ部分を模した書式に続けて0個以上のメッセージ式を連ねることで記述する。前出の、レシーバーか引数を比べてより小さな方を返す「min:」というメソッドの登録は次のようなものになる。anOtherObject」がメッセージパターンで、メソッド名(セレクター)と仮引数となる擬変数の宣言を兼ねる。念のためここでメソッド名は「min:」、仮引数となる擬変数名は「anOtherObject」である。メッセージパターンのあとに処理を続けて書くこともできるが、通常は行を改めて(さらに、ここでは省いたが慣習としてメソッドの説明をするコメントを書き、それに続けて)処理を記述する。値を返さないメソッドを書くことはできない。クラスオブジェクト[編集]Smalltalkは、多くの動的型付け言語やDelphiの様にクラスがオブジェクトである。このためSmalltalkではインスタンスオブジェクトと同様にクラスオブジェクトを変数に束縛してメッセージを送ることができる。"クラスオブジェクトにvalueメッセージを送信"クラスオブジェクトは、オブジェクトにclassメッセージを送ることでも取得できる。ブロックは一種の制御構文であるという性質上、復帰文が他の言語と比べ極めて異質な振る舞いをする。セレクターを使ったメッセージを送ると結果としては何が返ってくるか。ブロック内の復帰文からでもメソッド自体を抜けることができるようになっている。自体も中断して結果を返す。戻すようになっている。戻り値である1を返す。ブロック内で復帰文が実行された際、ブロックの生成地点の呼び出し元までコンテキストを巻き戻すようになっている。セレクター等を使った反復処理を復帰文だけで中断する事ができるようになっている。0.ただし、上記の様にブロックを生成したコンテキストと、ブロックを評価する際のコンテキストが枝分かれする様な場合は復帰文を実行する事はできない。例外を出力し処理が停止してしまう。入出力等の実現や、特定の目的のメソッドを自動で列挙するといった目的で使用される特殊構文である。いくつかの注釈はSmalltalk環境に組み込まれているが、利用者やライブラリーの提供者が注釈を定義する事も出来る。メソッドに対する注釈はメソッドの翻訳時に評価されるため、メソッドにしか記述でない。Behaviorのevaluate:による評価などメッセージ式をメソッドの外部で評価する場合は、評価対象の式に注釈を含める事はできない。具体的にはSmalltalk環境のWorkspaceに注釈を記述して評価するとエラーとなる。メソッドに対する注釈は次の様に記述する。><と>で囲まれた範囲は、メッセージ式のメッセージ部分と同じになる。引き数を取らない注釈の記述はできない。次にメソッドに対する注釈の具体例を挙げる。注釈はSmalltalk環境によって異なり、どの環境でも次の注釈が使えるわけでない事に注意すること。数値演算など原子的機能の呼び出し。引き数の値は呼び出す機能の番号。FFIによる外部関数の呼び出し。先頭のapicallは呼び出し規約であり注釈の名前ではない。cdeclなどもある。大域変数[編集]Smaltallkでは、Smalltalk環境全体で参照できる大域変数を作成する事が出来る。大域変数は同じく大域変数であるSmalltalk変数に格納されたSmalltalkImageのインスタンスオブジェクトにメッセージを送って作成する。大域変数の削除もSmalltalkImageのインスタンスオブジェクトに対するメッセージ送信となっている。"->nil"SmalltalkImageは一種の連想配列であり、Smalltalkの大域変数は、Smalltalk変数を介す事で連想配列として操作する事が出来るようになっている。Smalltalkのクラス名と大域変数は同じものであり、クラス名にオブジェクトを代入すれば、そのクラスを破壊してしまうことが出来る。Smalltalkオブジェクトが格納されたSmalltlak変数もオブジェクトを代入し破壊する事が出来る。このように大域変数を代入により破壊してしまった場合は、最悪Smalltalk環境が起動しなくなる事態に陥り非常に危険である。このためSmalltalkではよほどの理由がなければ大域変数を使うべきではない。プール辞書[編集]プール辞書は、クラスの変数として連想配列または、他のクラスオブジェクトのクラス変数を取り込むという機能である。取り込む連想配列の要素やクラスオブジェクトのクラス変数はプール変数と呼ばれる。連想配列やクラスオブジェクトは大域変数でなくてはならない。"UserPoolBのExamplePoolValueBを参照"!!プール辞書には複数の連想配列やクラスオブジェクトを指定できるが、プール変数が重複した場合は、先に指定した連想配列やクラスオブジェクトのプール変数が使われる。Smalltalkといった近代の環境では、定数以外に式の結果を指定可能な非定数要素の配列定数を使用できる。配列の要素は空白ではなく.で区切る。"1と2を要素に持つ配列を作る。Smalltalkで使用できる。反復の中断や、メソッド内の処理を飛ばすために使われる。継続の使用は次の様に記述する。"aCondition1がtrueなら以降の処理を中断しresultに1を代入する。"aCondition2がtrueなら以降の処理を中断しresultに2を代入する。aCondition2両方trueならresultに3を代入する。Smalltalkで使用できる。生成器はCoroutineにも利用できる。生成器の使用は次の様に記述する。nextを1回呼ぶまで実行しない。nextを2回呼ぶまで実行しない。3"生成器を使って処理を作ることは多くないが、配列などを使用する際、間接的に使用していることが多い。"#readStreamにより#select:を遅延実行する生成器が作られる。"#inject:into:でeachに代入するとき初めて#select:と#collect:と#reject:が実行される。GUI環境から行われる。ソースコードやプログラムを目にすることはない。環境外でソースコードを管理する必要がある場合に備えファイル用の構文が存在する。ファイル用の構文は次のようになる。0.!!本来他の言語の様なブロックが存在しないため、ブロックとして「!」が使用される。クラスの登録は「!」の一組で囲まれる。!!」というブロックで囲まれる。一つのプロトコルには複数のメソッドを定義でき、メソッド同士は一個の「!」によって区切られる。ちなみに、クラス登録は単なるメッセージ送信であり特別な文ではないため、登録用ブロック外にも次のように単純なメッセージ送信の記述に使用する事が出来る。!selector!!ファイル用構文で記述されたメソッドの登録は、可読性や記述性の面からメッセージ式からかけ離れた変則的な構文が使用される。この変則的な構文を用いなければメソッドを登録できないわけではなく、次のように通常のメッセージ式でメソッドを登録する事も出来る。Cに対し、メソッドselectorCを登録している。おいて、継承とは特殊な委譲に過ぎない。メッセージを送る事で、基底クラスに別のクラスオブジェクトを指定する事が出来る。NewBase.処理系により不可能な事もあるがクラスオブジェクトだけでなく、インスタンスオブジェクトから派生することも出来る。環境に登録する"nilsubclass:#DerivedinstanceVariableNames:''classVariableNames:''poolDictionaries:''category:'example'.なお通常、派生元の基本となるProtoObjectやObjectはnilから派生しており継承関係は再帰的に循環している。おいて、メッセージ、セレクター、メソッドはそれぞれ別物である。系統の言語の様にオブジェクトに対しメッセージを送るという事は単なる比喩ではない。いうセレクターを使ったメッセージを送る事を考える。いうメソッドが必ず呼ばれる保証はない。メソッドが呼ばれる事になる。引き数で得られたメッセージを返すだけのクラスが用意されている。用意されており[27]次のようにメッセージを拾い、他のオブジェクトに渡すことが出来る。'text'」がmessageに代入される。'text'」が実行される。"また、セレクターとメソッドが独立していることを利用して一つのメソッドを複数のセレクターに結びつける事もできる。"#onClick:を使ったメッセージをopen:メソッドに転送させる。#open:.「メッセージ転送」も参照メッセージにはセレクターと引き数が含まれている。このため受け取ったセレクターと引き数を編集する事も出来る。cr.]."以下が出力される。untyped)に区分される[28]。場合、変数に対する操作は全てメッセージ送信であり、変数の種類(型)毎にできる操作は決まっていない。オブジェクトに対しメッセージを送った場合、そのオブジェクトがメッセージに対応するメソッドを持っていなくとも実行環境がエラーを発生させる事はない。メッセージに対応するメソッドが存在しない場合、例外を出すか無視するかは、クラスに実装されたメソッドの内容次第である。全てのメッセージを拾うため、どんなメッセージを与えられても例外が発生することはない。Smalltalkではnilから派生したクラスのオブジェクトに存在しないメソッドに対するメッセージを送ると何も反応しない。高速化のため後述の特殊セレクターを使用した場合実行時に型検査する処理系が多い。基本的に中間言語に翻訳され、翻訳時にエラーを発生させるため構文検査は静的である。メッセージと制御構文[編集]制御構文の節で述べた通り、Smalltalkの殆どの制御構文はメッセージ式である。Smalltalkに明るくないプログラマーからは言い方や見方を変えただけと捉えられがちである。Smalltalkの制御構文は実際にメッセージであるがゆえに究極には制御構文の構文要素を次のように変数に分解してしまうことが出来る。condition.これらの変数に分解された構文要素は、どのクラスのオブジェクトで無いといけないという制限はない。送られたメッセージを処理することさえ出来ればあらゆるオブジェクトに置き換える事が出来る。特殊セレクター[編集]Smalltalkでは高速化のためいくつかのメッセージを特別扱いする。selector)という。典型的な例は#ifTrue:ifFalse:である。[6]」を評価した時にメッセージが送られる訳ではなく、バイトコードレベルでインライン展開され飛越し命令の表現に置き換えられる。いう名のメソッドが呼ばれることもない。trueやfalse以外に上記のようなBoolean用のメッセージを送ると処理系によってはMustBeBoolean例外を発生させる。このように頻繁に使用する分岐や反復を特別扱いすることで性能低下を防いでいる。].セレクターと名がつくが特殊セレクターは、特別扱いする条件が引数の状態を含んでおり、たとえ同じセレクターを使ったメッセージでも引数が条件に一致しなければ特別扱いしない。Smalltalk等)は特別扱いせずメッセージ送信を実行する。else.特殊セレクターはあくまで高速化の手段であるため種類は処理系によって異る。どの処理系が何を特殊セレクターとして扱うかは処理系ごとに提供される説明資料に記述されている。[29][30]クラスオブジェクトとMetaclass[編集]クラスオブジェクトもオブジェクトであるため、所属するクラスが存在している。クラスオブジェクトが所属するクラスはMetaclassというクラスのインスタンスオブジェクトである。Metaclass"Metaclassも当然ながらクラスに所属しており、再帰的にMetaclassに属するようになっている。class"クラスオブジェクトが所属するMetaclassのインスタンスオブジェクトは特殊なオブジェクトであり、クラスの継承階層と同様に継承階層を持っている。Class"クラスオブジェクトはMetaclassから生成された単なるオブジェクトで有ることから、Smalltalkが標準で提供するクラスオブジェクトとは異なる独自の構造をもったクラスオブジェクトを作ることができる。以下のようにメソッドの変わりにブロックを持つ無名クラスを作成することも出来る。printString;nl."生成したクラスオブジェクトを基底クラスとして使用"classsubclass:#ExampleinstanceVariableNames:''classVariableNames:''poolDictionaries:''category:''.定数とオブジェクト[編集]文法の節で述べた通りSmallatalkでは定数も全てオブジェクトである。どんな定数であれ#classや#inspectといった基本的なセレクターを使ったメッセージを受け取ることが出来るため、基本的な操作であれば定数と他のオブジェクトを区別する必要はない。任意の広さで確保した領域を持つ可変長オブジェクトを作ることが出来る。Smalltalkには配列を表わすためArray等が存在するが、これらのクラスオブジェクトは可変長オブジェクトを使って構築されている。可変長オブジェクトの領域は、オブジェクトの生成したときの一度だけしか広さを指定できない。クラスオブジェクトの登録時にvariable〜で始まるセレクターを使っている必要がある。100."要素100個分の領域を確保した可変長オブジェクトを生成する。0."1番目の要素に0を入れる。1."1番目の要素を取り出す。ハンドルとごみ回収機能(ガーベッジコレクター)の全面的な導入によりハンドルテーブルの書き換えを利用した特殊な制御を提供している。[31]ハンドルテーブルの書き換え[32][編集]ハンドルが参照している記憶領域上のテーブルを書き換えることによりSmalltalkは、あるオブジェクトを参照している全ハンドルの参照先を一気に変更することができる。ハンドルテーブルの書き換えには#become:を用いる。数字や文字列といった定数オブジェクトは置き換えることはできず、定数を置き換える際は定数を保持しているオブジェクトを置き換える必要がある。"この時点でvalue2はValueHolder('こんにちは')になる"#become:を使っている良い例はクラスオブジェクトの再登録である。Smalltalkではクラスオブジェクトはインスタンスオブジェクトが生きている間でも再登録可能でなければならず、インスタンスオブジェクトを生きたままクラスオブジェクトを再登録するために使われている。弱参照[編集]弱参照は参照カウント方式を使う言語でよくライブラリーとして実装されるがSmalltalkではハンドルの制御を用いた言語機能として用意されており相互参照しているが不要になっているオブジェクトを迅速に解放するために使われている。弱参照には#makeWeakを用い、#makeWeakを受け取ったオブジェクトは弱参照となる。"holderが弱参照になる。valueはnilではない。valueはnilとなる。"カゲロウ(蜉蝣)[編集]カゲロウ(Ephemeron)は、どこからも参照されなくなった連想配列の要素を解放するために導入された記憶領域の管理機構でありSmalltalkで初めて実装された。連想配列の添字として#keyがあったとして、#keyが連想配列以外の変数で参照されていなければ連想配列の要素は必要ない。このように不要となった要素を解放するために用いる。オブジェクトをカゲロウ状態にするには#makeEphemeronを用いる。"associationがカゲロウになる。valueは共にnilではない。valueは共にnilとなる。"ここでは連想配列の要素としてよく使われるAssociationを例としているが、カゲロウが消滅する基準は最初のインスタンス変数でクラスに依存しないためどんなクラスでもカゲロウにすることができる。慣習[編集]大文字からはじめる識別子と小文字からはじめる識別子[編集]変数名[編集]変数を表す識別子については、1文字目に大文字と小文字のどちらを使うか、大域変数か否かを基準にして決めることが慣習になっている。環境自体も大文字小文字の使い分けを認識しておりメソッドを翻訳する際小文字の変数は局所変数かメンバーとして定義していないと、警告が発生したり翻訳失敗になる。小文字からはじめるクラス名が大文字から始まるのは、クラス名が大域変数だからである。使われるクラス以外の大域変数:SmalltalkProcessorTranscriptセレクター[編集]セレクターを表す識別子については、基本的に1文字目に小文字を使うが、メソッドが存在するセレクターを避けたい場合は大文字を使う事が慣習になっている。SmalltakやVisualWorksで用意されている名前空間は、大文字のセレクターを使う典型的な例である。"「Smalltalk」以外は全てセレクター"なお、名前空間が使える環境の多くは、翻訳時に名前空間の名前解決できる「.」区切りの拡張構文が用意されており、実際にはこちらの構文が使われることが多いため、セレクターを使った名前空間の指定を見る機会は少ない。セレクターを使ったメッセージを使う。"Exampleクラスオブジェクトに「new」メッセージを送りオブジェクトを生成。クラスオブジェクトのメソッドもインスタンスオブジェクトのメソッドと同様に派生クラスによる再定義が可能である。メソッドを再定義し初期化処理を記載する事が出来る。送ってオブジェクトを生成しているためオブジェクトの生成手段がなくなるわけではない。「basicNew」メッセージをBehaviorに送ることでインスタンスオブジェクト生成することが出来る。メソッドが使われる事は多くない。別の初期化用メソッドが使用される。「new」メッセージやその他のインスタンス・クリエイションを使って初期化済みのオブジェクトを生成する役割を持っているだけで基本的にその他のメソッドと変わらない。creationというプロトコルに登録される。「new」メッセージの送信によりできる初期化は1個のオブジェクトにつき一通りの初期化だけである。このため複数のインスタンス・クリエイションを用意することで用途に応じた複数の初期化方法を提供しているのである。インスタンス・クリエイションは一般的なメソッドのひとつでしかない。このためインスタンス・クリエイション持つクラスオブジェクトはアブストラクト・ファクトリーとして機能する。具体的には次のように使われる。defaultDatabase"既定のデータベースのクラスオブジェクトを定義した派生クラスで再定義可能なメソッド。オブジェクトが返される場合もある。PostgreSQL.database"databaseへの接続を返すメソッド。#connect:セレクターを使ったメッセージが送られ、PostgreSQLのインスタンスオブジェクトが生成される。PostgreSQLクラスオブジェクトに送られるとは限らない。クラスメソッドを上書きできるため、インスタンス・クリエイションを次の様に実装する事で基本的な初期化処理を派生元のクラスに任せることができる。aY.上記は、2次元座標用のクラスオブジェクトのインスタンスオブジェクトを初期化する派生元のクラスオブジェクトに実装されたインスタンス・クリエイションである。このクラスオブジェクトを継承した2次元座標用のクラスオブジェクトでは#x:y:セレクターを使ったメッセージに対応するメソッドを実装する必要はない。広く利用され、いたる所で見ることが出来る。単一の値を出し入れするメッセージの事を特にアクセッサ―[34]と呼ぶ。引き数の有無により値の入出の方向を区別する。accessing(アクセッシング)として登録される点が特徴的である。おいてアクセッサーはインスタンス変数の出し入れや、クラス変数の単純な出し入れに使用される事は多くない。おいてアクセッサーは次の用途でよく使われる。あればそれらの変数を初期化する。クラス・オブジェクトあるいはファクトリーオブジェクトを取得できるアクセッサ―を用意し、アクセッサ―を派生クラスでオーバーライドする事で派生クラスからオブジェクトの生成に使うクラス・オブジェクトを自由に切り替えられるようにする。オブジェクトが、インスタンス・クラス・プールのどこで管理されているかを抽象化する意味がある。クラス変数やプール辞書の操作では、クラス変数やプール辞書の操作目的であってもインスタンスオブジェクトのメソッドとしてアクセッサーを用意する。インスタンス変数やクラス変数に対しメッセージを送るアクセッサ―を定義し、複数の箇所でインスタンス変数やクラス変数に対する同じメッセージ送信をしないようにする。1.というメッセージに単純化する。定数[編集]定数は、単に定数を返すアクセッサ―で定義する。C言語の影響を受けた言語のように定数を#defineや変数で定義するという慣習はない。property)というパターンが使用される。附帯情報はインスタンス変数やクラス変数などの内部変数の代わりに連想配列によりオブジェクトを保持する仕組みである。aString.!!附帯情報が有効な身近な例としてはXMLやHTMLのタグ属性が挙げられる。いったイベント属性は、必ずしも全てのタグで使用されることはない。イベント属性については一つのHTML上に一切記述されない事もよくある。この様な使用頻度の低い属性のためにオブジェクトに一個一個変数を定義するのは記憶領域の無駄である。onClick、onMouseDown、onMouseUp等大量に属性があればこの無駄は馬鹿にならない。附帯情報というパターンがよく使用される。全てのインスタンス変数やクラス変数は原理的に全て附帯情報によって表現することが出来る。おける附帯情報(プロパティー)に由来するもので、附帯情報の仕組みの有無に関わらずインスタンス変数やクラス変数をプロパティーと表現するのは間違いである。おいては当たり前の様に使用されている。おいては附帯情報を多用する事はデバックを著しく困難にするため不適切な作法とされており、HTMLの属性の様に本当に使用頻度の低い変数だけを附帯情報で扱い、常用する変数に附帯情報を乱用すべきではないと言われている。変数は統合開発環境の機能で使用箇所を把握できるが附帯情報では使用箇所をアクセッサーに限定しない限り追跡不可能になる。附帯情報では変数の変化に反応するブレークポイントを仕掛けることも難しい。以外の言語において、配列の範囲外にある配列要素の操作や、値の代入されていない連想配列の操作は、次の例のように操作の前に一旦判定を行なって例外処理するか、例外機構を利用する方法が一般的である。配列の範囲外操作の様に単純で頻発するような処理では、次のように予めメッセージに例外処理をブロックとして渡してしまう方法が一般的である。