Self は、「プロトタイプ」の概念に基づいたオブジェクト指向プログラミング言語である。1980年代から1990年代にかけて言語設計の実験的システムとして使われていたが、2018年、Self の開発は続けられており、Self言語自身で書かれた Selfバーチャルマシンを構築する Klein プロジェクトが進められ、2006年7月にバージョン 4.3 がリリースされた。

Self
Logo
Selfのロゴ
パラダイム マルチパラダイム:
オブジェクト指向, プロトタイプ指向
登場時期 1986年
設計者 David Ungar、Randall Smith
開発者 David Ungar、Randall Smith、
スタンフォード大学
サン・マイクロシステムズ
最新リリース 2017.1/ 2017年5月24日 (7年前) (2017-05-24)
型付け 動的、強い型付け
主な処理系 Self
影響を受けた言語 Smalltalk
影響を与えた言語 NewtonScriptJavaScript
IoCelAgora
ウェブサイト www.selflanguage.org
テンプレートを表示

カテゴリ / テンプレート

歴史

編集

1986Randall SmithSelfSmalltalk-80Self1987Self

1990 Self1995 4.0 4.22004Mac OS XSolaris

SelfApple NewtonNewtonScript使JavaScriptIoCelAgora

プロトタイプベース・プログラミング

編集

:

(一)

(二)

Vehicle Porsche 911  Vehicle 1 911 Porsche 911 

 Vehicle  Vehicle 使Sports Car  Flatbed Truck Flatbed Truck Sports Car 

Smalltalk

Smalltalk 

C++

Self 

Self Porsche 911  Vehicle 使使使

言語としての記述

編集

Self のオブジェクトは「スロット」の集まりである。スロットとは、値を返すメッセージであり、スロット名の後にコロンをつければ値をセットするメッセージになる。例えば、"name" というスロットがあるとする。

   myPerson name

これは name の値を返す。

   myPerson name:'gizifa'

これは値をセットする。

Self は Smalltalk と同様「ブロック」を使って処理の流れを制御する。メッセージを受け取るメソッドはスロット群以外にコードを持つオブジェクトであり、任意のスロットの値としてメソッドを格納できる。メソッドの持つスロットは引数や一時変数として使われる。いずれの場合も文法的には同じである。

Self ではフィールドとメソッドに区別はなく、どちらもスロットである。メッセージによるスロットアクセスで Self の文法の大部分が説明されるため、自分自身(self)へのメッセージも多い。そのため "self" は省略できる(また、これが言語名の由来)。

基本文法

編集

 Smalltalk 3:



receiver slot_name



receiver + argument



receiver keyword: arg1 With: arg2

receiver  argument 
   'Hello, World!' print.

 Self Hello world'

使使
   valid: base bottom between: ligature bottom + height And: base top / scale factor.

:
   valid: ((base bottom) between: ((ligature bottom) + height) And: ((base top) / (scale factor))).

Smalltalk-80 :
   valid := self base bottom between: self ligature bottom + self height and: self base top / self scale factor.

新しいオブジェクトの生成

編集

もう少し複雑な例として次の記述を示す:

   labelWidget copy label: 'Hello, World!'.

"labelWidget" オブジェクトへの copy メッセージでコピーを作り、そのコピーの "label" スロットに "Hello, World" メッセージを格納すべくメッセージを送っている。これを使ってみると次のようになる。

   (desktop activeWindow) draw: (labelWidget copy label: 'Hello, World!').

この場合、(desktop activeWindow) が最初に評価され、desktop オブジェクトが知っているウィンドウのリストからアクティブウィンドウを表すオブジェクトが返される。次に(内側から外側へ、左から右へという順で)前掲のコードが評価され labelWidget が返される。最後にそのウィジェットがアクティブウィンドウの draw スロットに送られる。

継承/委譲

編集

 Self Self 

特徴

編集

例えば、「銀行口座」というオブジェクトを定義し、口座の残高を管理するとしよう。一般にこのようなオブジェクトには「入金」と「出金」のメソッドが作られ、それに必要なデータスロットも作られる。これはプロトタイプであるが、そのまま汎用の口座を表すオブジェクトとしても使える。

このオブジェクトのクローン「ボブの口座」を作ることで、上記オブジェクトがプロトタイプとして使われたことになる。このとき、そのオブジェクトが持つ全てのメソッドやデータがスロットとしてコピーされる。しかし、より典型的な手法は、もっと単純な traits object(特徴オブジェクト)と呼ばれるオブジェクトをつくり、そこにクラスに関連するものを含める。

この例では、「銀行口座」オブジェクトに入金や出金メソッドを備えさせるのではなく、その親オブジェクトに持たせる。このようにすると、多数の銀行口座オブジェクトのコピーを作っても、親オブジェクトの修正によって全銀行口座オブジェクトの動作を更新できる。

これはいわゆるクラスと何が違うのだろうか? 次の意味を考えてみよう:

   myObject parent: someOtherObject.

これは、'parent*' スロットに適当なオブジェクトを代入することで myObject の「クラス」を実行時に動的に変更できることを意味する(アスタリスクはスロット名の一部だが、メッセージには表記されない)。継承やスコープとは違い、委譲オブジェクトは実行時に変更可能である。

スロット追加

編集

Self '_AddSlots:' _AddSlots 使使

Vehicle Self :
   _AddSlots: (| vehicle <- (|parent* = traits clonable|) |).

'_AddSlots'  "self" "self"  "lobby" '_AddSlots' 1 'vehicle' "<-" 使 'vehicle:' 

"=" 'parent*'  'parent:'  'vehicle' 1(| |)  () 
    vehicle _AddSlots: (| name <- 'automobile'|).

'parent*'  'name'  'name:' 
   _AddSlots: (| sportsCar <- vehicle copy |).
   sportsCar _AddSlots: (| driveToWork = (何かのコード、これがメソッドになる) |).

 'vehicle'  'sportsCar' 
   _AddSlots: (| porsche911 <- sportsCar copy |).
   porsche911 name:'Bobs Porsche'.

 'porsche911'  'sportsCar'  'name' 

環境

編集

Self 1Smalltalk 使Self CSelf 

Self 

性能

編集

Self VMC

(JIT)adaptive compilationSelfJavaHotSpot

ガベージコレクション

編集

Self のガベージコレクションは世代型であり、オブジェクトを世代で管理する。メモリ管理システムを使ってページへの書き込みを記録し、ライトバリアを保つ。この手法は性能がよいが、ある期間実行を行っていると全体ガベージコレクションが発生し、無視できない時間を取られてしまう。

最適化

編集

C

関連項目

編集

外部リンク

編集