コンテンツにスキップ

Smalltalk

出典: フリー教科書『ウィキブックス(Wikibooks)』

Smalltalkは、オブジェクト指向プログラミング言語の一つです。 Smalltalkは、オブジェクト指向の最初の言語の一つであり、多くの現代的なオブジェクト指向プログラミング言語の基礎となっています。

このチュートリアルでは、Smalltalkの基礎的な文法、制御構造、オブジェクト指向プログラミングの概念を紹介します。

Smalltalkの基本

[編集]

Smalltalkは、すべてがオブジェクトであることが特徴です。Smalltalkには、数値、文字列、コレクション、メソッドなどのオブジェクトがあります。 Smalltalkのクラスは、オブジェクトの青写真であり、オブジェクトがどのように動作するかを決定します。

Smalltalkの実行環境

[編集]

Smalltalkの実行環境には、さまざまなオープンソース実装があります。一般的なものには、Pharo、Squeak、GNU Smalltalkがあります。Pharoを使用して、Smalltalkのコードを実行する方法を以下に示します。

Pharoをダウンロードして、インストールし、起動します。Pharoの起動後、ワークスペースを開き、Smalltalkのコードを入力し、評価ボタンをクリックすることで、コードを実行できます。

数値と算術演算子

[編集]

Smalltalkには、整数、浮動小数点数、分数、複素数などの数値型があります。算術演算子は、+、-、*、/などがあります。以下に、Smalltalkで数値を使用する例を示します。

5 + 3

"結果:8"

3 - 1

"結果:2"

2 * 4

"結果:8"

10 / 2

"結果:5"

文字列

[編集]

Smalltalkの文字列は、シングルクオートまたはダブルクオートで囲まれたテキストです。文字列を連結するには、#、、、を使用します。

'Hello' # 'World'

"結果:'HelloWorld'"

変数

[編集]

Smalltalkでは、変数は、コロン(:)で開始される識別子によって宣言されます。コロンに続く文字列は、変数名です。変数は、:=演算子を使用して初期化します。

| a |
a := 5.

この例では、変数aに5を割り当てています。変数aを使用して、他の数値を計算することもできます。

Smalltalkの歴史
Smalltalkは、1970年代にAlan Kayとその同僚たちによって、パーソナルコンピュータの革命を支えるために開発されたオブジェクト指向プログラミング言語です。彼らは、プログラムを理解し、簡単に再利用できるようにするために、プログラムをオブジェクトの集合として見ることができる言語を必要としていました。

Smalltalkは、最初のバージョンが1972年にリリースされました。その後、Xerox Palo Alto Research Center(PARC)での開発により、Smalltalk-76が開発され、Smalltalk-80が最終的にリリースされました。Smalltalk-80は、オブジェクト指向プログラミング言語の標準として広く認められ、Smalltalkの普及を促しました。

Smalltalkは、動的なオブジェクト指向プログラミング言語として知られています。プログラムは、オブジェクトの集合として表現され、これらのオブジェクトは、自己完結型であるため、自分自身を表現し、自分自身を変更することができます。これにより、Smalltalkは、プログラムの抽象化、モジュール化、再利用性を強化しました。

Smalltalkは、アプリケーション開発、GUIプログラミング、教育用プログラミング言語として広く使用されています。また、Smalltalkは、Ruby、Java、Pythonなどの多くの現代的なオブジェクト指向言語に影響を与えました。

メソッドと制御構造

[編集]

Smalltalkは、オブジェクト指向プログラミング言語であり、オブジェクトが相互にメッセージを送り合うことによってプログラムが実行されます。Smalltalkには、メソッドという概念があります。メソッドは、オブジェクトが受け取ったメッセージに対してどのように応答するかを定義するものです。

Smalltalkのメソッドは、以下のような構文で記述されます。

メソッド名 引数名1: 引数1 引数名2: 引数2 ...
    メソッドの本体

たとえば、次のようなメソッドがあるとします。

moveTo: x y
    self x: x.
    self y: y.

このメソッドは、オブジェクトが「moveTo:」というメッセージを受け取った場合に実行されます。このメッセージには、xとyという引数が含まれています。メソッドの本体では、xとyの値をオブジェクトの内部状態に格納するようになっています。

Smalltalkには、条件分岐やループといった制御構造がありますが、これらはすべてメッセージ送信によって実現されます。たとえば、次のようなメソッドがあるとします。

ifTrue: trueBlock ifFalse: falseBlock
    self value
        ifTrue: [ trueBlock value ]
        ifFalse: [ falseBlock value ]

このメソッドは、真偽値を返すメソッドに対して「ifTrue:ifFalse:」というメッセージを送信することによって、条件分岐を実現します。このメッセージには、trueBlockとfalseBlockという2つの引数が含まれています。trueBlockは、真の場合に実行されるメソッドを表し、falseBlockは偽の場合に実行されるメソッドを表します。

また、Smalltalkには、例外処理に利用される「try-catch-finally」の制御構造もあります。例外が発生した場合には、該当するcatchブロックが実行されます。finallyブロックは、例外の有無にかかわらず、必ず実行されます。

Smalltalkのメソッドと制御構造は、すべてメッセージ送信によって実現されます。このため、Smalltalkは非常にシンプルで一貫性のある言語となっています。

構成要素

[編集]
  1. コメント: コードに関する説明やメモを追加するための機能です。Smalltalkでは、ダブルクォーテーションで囲まれたテキストをコメントとして認識します。
  2. 定数(リテラル): 変更不可な値を表すもので、整数、浮動小数点数、文字列、シンボルなどが含まれます。定数は通常、変数に代入する前に定義されます。
  3. クラス: クラスはオブジェクト指向プログラミングの基本的な構成要素であり、オブジェクトの属性とメソッドを定義します。Smalltalkでは、クラスは必ず他のクラスのサブクラスであることが要求されます。
  4. 変数: 値を格納するための場所です。Smalltalkでは、変数は常にオブジェクトへの参照であり、オブジェクトが変数に割り当てられることになります。
  5. テンポラリ変数: ブロック内で一時的に使用される変数です。ブロック内で定義され、ブロックが評価されるときに作成されます。ブロックの外部からはアクセスできません。
  6. グローバル変数: アプリケーション全体で共有される変数です。Smalltalkでは、グローバル変数はグローバル名前空間に定義されます。
  7. メッセージ: オブジェクト間の相互作用を可能にする機能です。メッセージは、オブジェクトに送信され、オブジェクトはそのメッセージを解釈して適切な応答を返します。
  8. 単項メッセージ: 引数を必要としないメッセージです。例えば、"object class"は、"class"という単項メッセージを"object"オブジェクトに送信しています。
  9. 二項メッセージ: 一つの引数を持つメッセージです。例えば、"2 + 3"は、"+"という二項メッセージを"2"オブジェクトに送信しています。
  10. キーワードメッセージ: 複数の引数を持つメッセージです。例えば、"point x: 10 y: 20"は、"x:"と"y:"というキーワードを持つメッセージを"point"オブジェクトに送信しています。
  11. メッセージの優先順位: Smalltalkでは、メッセージがオブジェクトに送信されたときに、オブジェクトの種類によって異なるメソッドが呼び出されます。このとき、優先順位の高いメッセージが優先的に処理されます。
  12. 束縛: Smalltalkでは、オブジェクトに変数を束縛することができます。この変数は、オブジェクトの状態を表します。
  13. カスケード: Smalltalkでは、1つのオブジェクトに複数のメッセージを送信することができます。これをカスケードと呼びます。
  14. トランスクリプト: Smalltalkでは、トランスクリプトを使用して、メッセージやオブジェクトの値を表示できます。
  15. ブロッククロージャ: Smalltalkでは、ブロッククロージャを使用して、一連のコードをまとめて処理することができます。
  16. 条件分岐: Smalltalkでは、ifやcaseなどの条件分岐を使用して、プログラムの分岐を制御することができます。
  17. 繰り返し: Smalltalkでは、whileやforなどの繰り返し構造を使用して、同じ処理を繰り返すことができます。
  18. 間隔: Smalltalkでは、時間や周期的なイベントを制御するために、間隔を使用することができます。
  19. 順序がある集まり: Smalltalkでは、配列やリストなどの順序がある集まりを使用して、オブジェクトの集合を管理することができます。

チートシート

[編集]
"コメントはダブルクォートで囲みます"

"変数定義と代入"
| 変数名 |
変数名 := .

"定数の定義"
ConstantName := .

"ブロックの定義と実行"
[  ] value.

"条件分岐"
(condition) ifTrue: [ true の場合に実行する式 ] ifFalse: [ false の場合に実行する式 ].

"繰り返し処理"
[ 条件を満たすまで繰り返す式 ] whileTrue.

"配列の作成とアクセス"
| 配列 |
配列 := #(要素1 要素2 要素3).
要素 := 配列 at: インデックス.

"文字列の連結"
'文字列1', '文字列2'.

"クラスの定義"
Object subclass: クラス名
  instanceVariableNames: '変数名1 変数名2 ...'
  classVariableNames: '変数名1 変数名2 ...'
  poolDictionaries: ''
  category: 'カテゴリ名'.

"クラスのインスタンス化"
オブジェクト := クラス名 new.

"メッセージの送信"
オブジェクト メッセージ名: 引数.

コード例

[編集]
シンプルなコード例
| greeting name |
greeting := 'Hello'.
name := 'Alice'.
Transcript show: greeting, ' ', name asUppercase, '!'.
実行結果
Hello ALICE!
このコードは、変数 greeting に文字列 'Hello' を代入し、変数 name に文字列 'Alice' を代入します。そして、 greetingname を結合した文字列を作成し、大文字に変換して、最後に ! を追加します。 asUppercase メソッドは、文字列を大文字に変換するためのメソッドで、 ', ''!' も文字列として扱われます。
Smalltalkでは、すべてがオブジェクトであるため、文字列や数値などの基本的なデータ型もオブジェクトとして扱われます。
また、 Smalltalkでは、メソッドの呼び出しは、 オブジェクト メッセージ引数 の形式で表現されます。上記の例では、 name オブジェクトに asUppercase メッセージを送信しています。
1から100までの素数を求める
primes := OrderedCollection new.
2 to: 100 do: [:i |
    (2 to: (i-1)) do: [:j |
        (i \\ j) = 0 ifTrue: [^false]
    ].
    primes add: i.
].
このプログラムでは、2から100までの整数を1つずつiに代入して、2からi-1までの整数を1つずつjに代入して、iをjで割った余りが0かどうかをチェックしています。もし余りが0であれば、iは素数ではないため、falseを返してループを終了します。素数であれば、primesというコレクションにiを追加します。
フィボナッチ関数
fibonacci: n
    "n番目のフィボナッチ数を計算する"
    | a b |
    a := 1.
    b := 1.
    n timesRepeat: [
        | temp |
        temp := a + b.
        a := b.
        b := temp.
    ].
    ^ a.
この関数は、引数として整数の n を取り、n 番目のフィボナッチ数を計算して返します。この関数は、繰り返しを使用して、フィボナッチ数列の各項を計算します。ab は、2つの直近のフィボナッチ数を表します。最初に、ab に1を代入して始めます。次に、n 回の繰り返しを実行して、フィボナッチ数列の次の項を計算します。temp 変数に a + b を代入し、ab に、そして btemp に代入します。最後に、最初のフィボナッチ数を返します。