「7つの言語 7つの世界」を読みました。

- 作者: Bruce A. Tate,まつもとゆきひろ,田和勝
- 出版社/メーカー: オーム社
- 発売日: 2011/07/23
- メディア: 単行本(ソフトカバー)
- 購入: 9人 クリック: 230回
- この商品を含むブログ (64件) を見る
Ioが面白いです。もっとも検索しにくいプログラミング言語のひとつ(らしい)。かつて「るびま」で紹介されていて存在だけは知っていたんですがそのときはピンときませんでした。
いま改めて触れてみて。変態さ(失礼)と実用性を兼ね備えた面白い言語だと感じです。
しばらく勉強ノートを書き散らかしていこうかと。
ちなみに。「Io」だと検索しにくいのでタグは「Iolanguage」にしときます。
「1日目」
「7つの言語 7つの世界」では各言語を3日で俯瞰するという体裁を取っています。まずはその構成にそって基本の学習。
IoをREPLモードで実行。数字はバージョン番号(というかそのバージョンのリリースの日付)です。
$ io Io 20110905 Io>
文字列を表示する。
Io> "Hi ho, Io" println Hi ho, Io ==> Hi ho, Io
文字列のオブジェクト"Hi hi, Io"にprintlnメッセージを送っています。オブジェクトはprintlnメッセージを受け取ると自分自身を出力して改行します。結果(式の値)は自分自身(このばあい、もとの文字列)です。
新しい型(type)のオブジェクトを作る。
Io> Vehicle := Object clone ==> Vehicle_0x473b40: type = "Vehicle"
オブジェクトはプロトタイプとなるオブジェクトのクローンとして作成します。プロトタイプのオブジェクトにcloneメッセージを送るとクローンのオブジェクトを作成します。このとき、名前に大文字から始まる識別子を使うとtypeスロットに名前が入ります。
Io> Vehicle type ==> Vehicle
小文字から始まる名前だとtypeは設定されません。
Io> vehicle := Object clone ==> Object_0x3afda0: Io> vehicle type ==> Object
オブジェクトのスロットに値を代入する。
Io> Vehicle description := "Something to take you place" ==> Something to take you place
Ioの代入演算子は標準で3種類あります。
| 演算子 | 対応するメソッド | 内容 |
|---|---|---|
| ::= | newSlot | あらたにスロットとセッターを作り、指定された値を代入する |
| := | setSlot | あらたにスロットを作り、指定された値を代入する |
| = | updateSlot | 既存のスロットに、指定された値を代入する |
演算子とメソッドの対応付けはOperatorTableで確かめることができます。
Io> OperatorTable (中略) Assign Operators ::= newSlot := setSlot = updateSlot (後略)
ちなみに。OperatorTableは特別なオブジェクトなのか、2012/03/03現在、リファレンスのなかに説明を見つけることができません。
::=演算子を使うと、たとえばここではfooというスロットの他にセッターであるsetFooというスロットも作成され、そのスロットに値が代入されます。
Io> Vehicle foo ::= "FOO" ==> FOO Io> Vehicle ==> Vehicle_0x473b40: description = "Something to take you place" foo = "FOO" setFoo = method(...) type = "Vehicle"
setFooの中身はこうなっていてfooに値を設定したあと自分自身(ここではVehicleオブジェクト)を返しています。
Io> Vehicle getSlot("setFoo")
==> # doString:1
method(
foo = call evalArgAt(0); self
)
:=演算子を使うと、スロットを作成しそのスロットに値が代入されます。
Io> Vehicle bar := "BAR" ==> BAR Io> Vehicle ==> Vehicle_0x473b40: bar = "BAR" description = "Something to take you place" foo = "FOO" setFoo = method(...) type = "Vehicle"
=演算子は既存のスロットに値を代入します。新たにスロットを作成しないので存在しないスロットに代入しようとすると例外が発生します。
Io> Vehicle foo = "FOOOOOOOOOO" ==> FOOOOOOOOOO Io> Vehicle baz = "BAZ" Exception: Slot baz not found. Must define slot using := operator before updating. --------- message 'updateSlot' in 'Command Line' on line 1
現在のVehicleのスロットの状態の確認。
Io> Vehicle slotNames ==> list(foo, bar, setFoo, type, description)
Vehicleを継承したCarオブジェクトを作る。
Io> Car := Vehicle clone ==> Car_0x500a90: type = "Car"
Vehicleにはcloneというスロットはありませんが、VehicleはObjectを継承しているのでObjectのcloneが実行されます。
Carも大文字から始まっているので、typeスロットが作られています。
Io> Car slotNames ==> list(type)
Carにdescriptionメッセージを送ります。
Io> Car description ==> Something to take you place
(継承元の)Vehicleで設定されているdescriptionの値が得られます。
Carのクローンを作ります。
Io> ferrari := Car clone ==> Car_0x4315d0:
このばあい、名前が大文字から始まっていないのでtypeスロットは作られません。
Io> ferrari slotNames ==> list()
(ferrariオブジェクトはスロットをひとつも持っていない)
ferrariオブジェクトのtypeを調べると、継承元のCarのtypeが使われます。
Io> ferrari type ==> Car
見た目、クラスとインスタンスのような関係になります(あくまで見た目上ですが)。
メソッドは次のように作成します。
Io> method("So, you've come for an argument." println)
==> method(
"So, you've come for an argument." println
)
ここで作成されたメソッドもまたオブジェクトです。
Io> method("So, you've come for an argument." println) type
==> Block
typeは[http://www.iolanguage.com/scm/io/docs/reference/index.html#/Core/Core/Block:title=Block]のようです。
オブジェクトなのでスロットに代入できます。
Io> Car drive := method("Vroom" println)
==> method(
"Vroom" println
)
スロットに代入されたメソッドは、当然そのスロットを持つCarから実行ますが、Carをプロトタイプに持つオブジェクトからも実行できます。
Io> ferrari drive Vroom ==> Vroom
オブジェクトのプロトタイプはprotoで調べることができます。
Io> ferrari proto ==> Car_0x365550: drive = method(...) type = "Car" Io> Car proto ==> Vehicle_0x348730: bar = "BAR" description = "Something to take you place" foo = "FOOOOOOOOOO" setFoo = method(...) type = "Vehicle" Io> Vehicle proto ==> Object_0x300530: (スロット多数のため省略)
マスター名前空間はLobbyというオブジェクトになります。ここまでで使ってきたCarやferrariは、Lobbyのスロットとして管理されています。
Io> Lobby ==> Object_0x30f810: Car = Car_0x365550 Lobby = Object_0x30f810 Protos = Object_0x30f780 Vehicle = Vehicle_0x348730 _ = Object_0x30f810 exit = method(...) ferrari = Car_0x36ce70 forward = method(...) set_ = method(...)
…長くなったので、続きはまた後ほど。