vieweditattachhistorytopchangessearchhelp

第25回


■SqueakではじめるSmalltalk入門   第25回


 本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。

 これまで、手っ取り早くSmalltalk言語を使ったプログラミングを体験していただこうという思いから、既存のオブジェクトについては最低限にしか触れてきませんでした。しかし、それもぼちぼちツラくなってまいりましたので、身近なオブジェクトの解説を一気に済ませてしまいたいと思います。まず、リテラル式で生成できるオブジェクトです。

 すべてをメッセージ送信で表現するSmalltalkシステムにおいてオブジェクトは、それが属するクラスにメッセージ「new」かそれに準じるメッセージを送って生成するのがスジです。しかし、よく使用する“馴染み”のオブジェクトについてはリテラル式、つまりメッセージ送信を介さずにそのものズバリを直接表現することができるよう配慮されています。

3                    "an Integer                     "
16r82A0              "an Integerの16進表現(n進可能)"
3.0                  "a Float                        "
$x                   "a Character                    "
'string'             "a String                       "
'It''s mine!'        "a Stringで'を含むとき          "
#symbol              "a Symbol                       "
#'s y m b o l'       "a Symbolでスペースを含む場合   "
#(1 2 3 4)           "an Array                       "
#('this' #is $a 10)  "an Array                       "


 では、普通の言語ではあまり見かけない、あるいはちょっと勝手が違うオブジェクトについてコメントしてまいりましょう。

▼シンボル
 シンボル(a Symbol)は要素を変更できず、かつ、同じ内容なら同じオブジェクトであることが保証されたオブジェクトです。たとえば、変更不可(immutable)であることは、次の式で確認できます。

'string' at: 4 put: $o; yourself  "=> 'strong' "
#symbol at: 5 put: $a; yourself
   "=> Error: symbols can not be modified. "


 メッセージ「at: n put: obj」はn番目の要素をobjと置き換える破壊的なメソッド「#at:put:」を起動し、objを返値として返します。「;」は前の式の返値ではなくレシーバに続くメッセージを送るとき使う記号です。メッセージ「yourself」はレシーバ自身をレシーバに返させます。【註1】 シンボルは内容を変える操作を受け付けません。

 他方で、シンボルの同内容の同一性保証は次のような作業で確認できます。

| str1 str2 sym1 sym2 sym3 |
str1 _ 'abc'.
str2 _ str1 copy.
sym1 _ #abc.
sym2 _ sym1 copy.
sym3 _ #($a $b $c) as: Symbol.
World findATranscript: nil.   "トランスクリプト呼び出し "
Transcript
   cr; show: str1 = str2;    "=> true  "
   cr; show: str1 == str2;   "=> false "
   cr; show: sym1 = sym2;    "=> true  "
   cr; show: sym1 == sym2;   "=> true  "
   cr; show: sym1 = sym3;    "=> true  "
   cr; show: sym1 == sym3    "=> true  "


 「= obj」はレシーバとobjとが同内容かを、「== obj」は同一かを確認するためのメッセージです。メッセージ「copy」はレシーバと同内容で別のオブジェクトを作るのですが、シンボルではそうなっていないことが分かります。これは、Symbol >> #copyの定義(再定義)を見ても明らかです。

[fig.A]Symbol >> #copyの定義
Uploaded Image: 25a.png

 メソッドはコメントのみで何も記述されていないように見えますが、このような場合、暗黙の「^ self」が機能して、self、つまりレシーバを返します。sym3の例でもお分かりいただけるように、コピー以外の方法で作られたシンボルについても同一性が保証されています。

 スペースを含むシンボルをリテラル式で表現することも可能です。ただし、そのようなときは、#の後に、文字列のリテラル式、つまり「'」で括って記述します。

 シンボルは、辞書のキーなどにおいて文字列の代わりに使用します。

▼文字列
 文字列(a String)のリテラル式で「'」を含むときは、これを2つ連ねることで表現します。

▼配列
 配列(an Array)は、要素をスペースで区切って表現します。ただし、配列のリテラル式では、要素がリテラルの配列しか作れません。シンボルの「#」は(そのシンボルがスペースを含まない場合にかぎり)省略することができます。

 くわえて、Squeak用Smalltalk言語独自【註2】で、他のSmalltalk言語にはない配列の表現方法に、カーリーブレイス表現というのがあります。カーリーブレイスとは、中括弧「{ }」のことです。カーリーブレイス内の式は、評価され、その返値が配列の要素になります。したがって、配列のリテラル式ではできない、リテラル以外の要素を含む配列を表現することが可能となります。

{3 + 4. 3 * 4. 3 - 4}   "=> #(7 12 -1) "


 余談ですが、カーリーブレイス表現を持たない通常のSmalltalk言語では、同様のことをするのに、Array class >> #with:、#with:with:、#with:with:with:、#with:with:with:with:などを使用します。

Array with: 3 + 4 with: 3 * 4 with: 3 - 4  "=> #(7 12 -1) "


 配列の要素への参照には、通常の言語に見られる添え字を使った特別な構文は用意されていません。先のシンボルや文字列のときと同様に「at: n」あるいは「at: n put: obj」というメッセージを介して行ないます。しつこく繰り返すと、Smalltalk言語においては、何ごとも常に「オブジェクトに対するメッセージ送信」なのです。もっとも、リテラル式の話をしているときにこのドグマを持ち出すのは、いささか説得力に欠けるというものですが…。

#(10 20 30 40) at: 3                      "=> 30 "
#(10 20 30 40) at: 3 put: 100; yourself   "=> #(10 20 100 40)


▼注釈、コメント
 オブジェクトではありませんが、コメントはダブルクオート「"」で括って表現します。コメント内でのダブルクオートは、文字列のときと同様に、二回繰り返すことで使用できます。

"She said, ""It's mine!"""


 もっとも、コメントの場合、このようにしてまでダブルクオートをあえてコメント内に含めることにそれほどの意味はないでしょう。ただ、既存の式をコメントアウトしたいとき、ダブルクオートを含んでいないかを注意する必要はありそうです。逆、つまりコメントアウトした式を復活させるときについても同じことが言えます。

 Smalltalk言語では、文字列リテラルもコメントも改行を含むことができます。


註1:レシーバそれ自身を返すメッセージ「yourself」は、もちろん単独では意味をなしませんが、「at: n put: obj」のようにレシーバを返さない(あるいは、返すことが保証されていない)メソッドの直後にレシーバを参照したい場合などに、「;」と併せてよく用います。これは、テンポラリ変数の使用を端折って簡潔に表現するための、ある種のイディオム(慣用的表現)です。

註2:カーリーブレイスは、より正確にはSqueakではなく、Squeakの前身のApple Smalltalk時代にラリー・テスラーの手により加えられた拡張です。ラリー・テスラーは、古くからのMac用ソフト開発者の間でその名前知らない人はいないほどの有名人ですが、同時に、Apple移籍前のPARC時代、Smalltalkシステムの拡充に大きく貢献した人でもあります。

このページを編集 (6247 bytes)


Congratulations! 以下の 1 ページから参照されています。

This page has been visited 1047 times.