MOSA Multi-OS Software Artists

MOSAはソフトウェア開発者を支援します

  • iPhone/iPod touch アプリ紹介
  • MOSA掲示板
  • 活動履歴
  • About MOSA(English)

MOSA Developer News[MOSADeN=モサ伝]第123号

2004-08-03

目次

  • SqueakではじめるSmalltalk入門   第5回  鷲見正人
  • 藤本裕之のプログラミング夜話 #50
  • 高橋真人の「プログラミング指南」 第49回
  • ニュース・解説

SqueakではじめるSmalltalk入門   第5回  鷲見正人

 本連載では、名前はよく耳にしていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回は前回提示した短いペイントスクリプトの内容に順を追って解説を加えます。

前回のプログラムは次のようなものでした。便宜的に、行頭にはコメントのかたちで行番号を振ってあります。

"01" | pen |
"02" pen _ Pen new.
"03" pen defaultNib: 3.
"04" pen color: Color red.
"05" [Sensor shiftPressed] whileFalse: [
"06"    | position |
"07"    position _ Sensor peekPosition.
"08"    Sensor redButtonPressed
"09"       ifTrue: [pen goto: position]
"10"       ifFalse: [pen place: position]]

 Smalltalkのプログラムコードは、目が慣れてしまえば、自然言語(英語)の文章を読むように、比較的容易にその内容を理解できるのがその特徴です。もちろん、変数名やメソッド名(セレクタ)を考える際に、それを使って書いたコードが、平易で読み下し易いものになるよう心がけることが推奨されており、ユーザー(プログラマ)がそれを遵守することが前提です。結果、変数名やメソッド名は長くなりがちですが、組み込みエディタの簡易補完やコンパイラのスペル修正機能のサポートが期待できるので、初期のProject Builderにおける、Objective-C/CocoaプログラミングやAppleScriptプログラミングのときのようなストレスを心配する必要はないでしょう。

1行目は、一時変数「pen」の宣言です。ちなみに、複数の一時変数を宣言したいときは、スペースで区切って列挙します。FORTRANやALGOLの流れを汲む言語でよく見られる「,」(コンマ)を区切り記号に使わないのは、Smalltalkが前二者よりLISPからの影響を強く受けているからだと思います。余談ですが、コンマは「コレクション」と呼ばれる配列の仲間(文字列を含む)のオブジェクト同士を連結するときに用いる二項セレクタ(関数名)として登録されているので、項目列挙の際に区切りのつもりでうっかり使うとエラーになったり、思わぬ結果が生じることもあるので気を付けてください。

#(1 2 3 4), #(5 6 7) “=> #(1 2 3 4 5 6 7) 配列の結合 ”
‘This is a ‘, ‘pen.’ “=> ‘This is a pen.’ 文字列の結合 ”

 話を戻して、2行目は宣言した一時変数「pen」に、クラス「Pen」のインスタンスを束縛(代入)しています。Smalltalkの変数は型を持たないため、中にデータを入れる“箱”というよりは、本来無名のオブジェクトに付ける“名前”になぞらえたほうがしっくりきます。また、ここで「代入」や「命名」ではなく「束縛」という言い回しをするのは、変数への束縛が、単に名前を付けるというだけでなく、オブジェクトの寿命を決定づける意味合いも持つからです。仮に「Pen new」を評価してオブジェクトを生じさせても、そのまま放っておけばガベージコレクタに瞬殺されてしまいます。誕生させたオブジェクトを確保し、続く式でメッセージを送って何らかの振る舞いをさせるための参照と延命のための作業が、変数への“束縛”、というわけです。

前後しますが「Pen new」は、クラス「Pen」にメッセージ「new」を送信してオブジェクトを生成するための式です。クラスはオブジェクトの設計図と言うべき存在で、そのクラスに属するオブジェクト(インスタンス)が内部にいくつのメモリ(インスタンス変数)を持ち、どんなメッセージに応答でき(セレクタ)そのときどんな振る舞いをするか(メソッド)を定義します。システムは、クラスの定義記述に従ってオブジェクトを生みだし、しかるべく振る舞わせます。

Smalltalkでは、クラスもまたオブジェクト(クラスのクラスの唯一のインスタンス)なので、メッセージを受けることができ、それに相応しい決められた振る舞いをします。メッセージ「new」は、そのクラスに属するインスタンス(オブジェクト)を生成するために送る一般的なメッセージです。クラス「Pen」は有名な、しかしSmalltalkが発祥だとは意外と知られていない「BitBlt」(bit block transfer)クラスのサブクラスで、LOGOの“タートル”のような振る舞いをするオブジェクトを定義します。

二つ以上の式を区切って区別するには「.」(ピリオド)を用います。これは終端記号ではないので、最終行には付ける必要はありません(あってもエラーにはなりません)。改行や余計なスペース、タブは式の解釈には影響を与えないので、主に可読性向上を目指した整形のために用います。

 3行目と4行目では一時変数「pen」に束縛した、Penのインスタンスに対してメッセージを送ることで、その“状態”を変化させています。3行目で送っているメッセージ「defautlNib: 3」はペン先(nib)の太さを3ドットに変更するためのもので、4行目の「color: Color red」はペンの色を赤に変えるためのものです。念のためおさらいしておくと、前者のセレクタは「#defaultNib:」パラメータは「3」、後者のセレクタは「#color:」パラメータは式「Color red」の返値となります。式「Color red」自体もメッセージ式で、クラス「Color」に「red」というメッセージを送りColorに属する“赤い色”というオブジェクトを生じさせています。同様に、「Color blue」とすれば“青い色”、「Color green」とすれば“緑色”を指定できます。

これでペン「pen」の準備ができたので、あとはマウスの動きにpenの動きを、マウスボタン操作にpenの上げ下げ連動させればお手軽ペイントソフトを機能させることができます。この部分を記述したのが5行目以降です。

次回は、ループやif-then-elseといった条件分岐を、通常のプログラミング言語がするような「構文」ではなく、どのようにして「式」で表現しているのかを解説します。

サポートページ:
http://squab.no-ip.com:8080/mosaren/

藤本裕之のプログラミング夜話 #50

 突然思い出したが、WWDCに行ったサンフランシスコでいきなりタカハシさんに「フジモトさん、OOP入門はどうなったんですか」と訊かれたのだった。「え、あれで終わりだけど」と答えると、チッチッと言う感じで指を振り「全然終わってないですよ」と。
 いやあのその別にC++とかObjective-Cの教科書みたいに網羅的にやるつもりは最初からなくて、あの最中にも書いたと思うけれどもオブジェクト指向プログラミングの、なんつうか取っ付きの悪い概念とか仕組みについて地に足がついたコトバで解説してみたかっただけなのでその、オレとしては当初の目論見は達したというかしどろもどろ、と言い訳をしたんだが、「でも例えば多重継承とかは……」とタカハシさんは追及するのだった。
 はい、その通り。継承についてはしつこく説明したけれども多重継承については一言も書いてない。何故ってねぇ、オレはキライなのだあの「多重継承」というヤツが。「キライったってお前、そういうもんぢゃないだろう」と口をトンガラかすキミの顔が目に浮かぶ……わけもないが、とにかくそういうことなので、今回は、オレがなんでコイツを嫌うか、という理由を通して多重継承についての説明を試みたいと思う。

まず基本的なコトなんだけど、多重継承というのはつまり、あるクラスが互いに継承関係のない複数のスーパークラスを持っている状態のことである。C++では例えば以下のように書く。

class Animal { ... };
class Bird { ... };
class Bat : public Animal, public Bird { ... };

 上の場合、BatというクラスはAnimalおよびBirdをスーパークラスとして持つ。両方ともpublicであるから(難しい言葉では「公開派生」とか言う)、Animalの持つメソッドもBird固有のメソッドもBatに対してコールすることができる……。
 便利ぢゃないかって? サイテーである(いや、個人的見解だからね)。
 オレが気に入らないのは、これが文字通り「コーモリはケモノである,でも空を飛ばなくちゃヘンだからトリでもある」ということを可能にしてしまう仕組みだからである。つまり「現実世界を模式化することでプログラムの構造を簡潔にできる」ことがウリのオブジェクト指向の理念に反して、この機構は「現実世界にはあり得ないモノを作り出してしまえる」のだ。なにが問題か分からない? 有り体に言えばこの多重継承という機構には「設計をちゃんとできないプログラマの味方」という側面があるのだよ。
 よくできたオブジェクト指向のプログラムはパーツパーツが独立していながら総体として一つのシステムを為している。前にも書いたと思うが、我々が意識しなくても心筋は脈動し全身に血液を行き渡らせるし、ランゲルハンス島は血糖値に応じてインシュリンを分泌するわけだ。ところがそういううまい設計をしなくてもなんとかなってしまうヤリカタがある。心筋からランゲルハンス島まで全ての機能をサブクラスして1つのクラスを作るのだ。
 言ってること、わかるでしょ? 多重継承というのは使いようひとつでオブジェクト指向をオブジェクト指向でなくしてしまうことのできる(そしてヘタなプログラマはそういう風に使いがちな)困った機構なのである。

正直に言うとオレ自身,かつてC++で書いたプログラムの中に「苦し紛れにやった多重継承」が散見できる。もちろん言い訳はあって、最初からそんなヌエみたいなオブジェクトがゴロゴロあったわけではなく、バージョンアップとかのときにオブジェクト相互の関係をできるだけ壊さないで(つまり構造を変えないで)、要求されている新機能を加えようとしてそうなっちゃったんだが、それを見るたび全部書き直したくて胃が焼けるような思いだった(今はもう多重継承のできないObjective-Cで書き直したので胃は痛くない)。
 と、こういうわけでワタシは多重継承がキライなんであり、多重継承というのはそういうものなんであった。わかっていただけたであろうか。わかんないか。
(2004_07_30)

高橋真人の「プログラミング指南」第49回

オブジェクト指向のとっかかり(34)

〜Macにおけるオブジェクト指向(続)〜

 こんにちは、高橋真人です。さっそく続きです。
 Core Foundationで最も使われるのはCFStringでしょう。これは文字列のための仕組みで、単なる文字の配列で作られるCの文字列とは違って、いくらかの応用力を持っています。
 たとえば従来のMac OSにおいて文字コードの変換に使われていたText Encoding Converterですが、Core Foundationの文字列関係の機能を使うことで直接呼び出す必要がなくなります。
 具体的な例として、Shift JISで作られたファイルをEUCに書き出すというケースを考えてみます。
 最初に読み込みデータを「これはShift JISのデータである」と指定してCFStringに読み込ませます。CFStringは内部ではデータをUnicodeで保持することになっているので、従来Shift JISの処理に付きものだった「上位バイト、下位バイト」といったことにもわずらわされずに文字列処理をすることができます。
 処理が終わって書き出す段になったら「EUCのデータとして書き出せ」と指示してやればよいというわけです。
 さて、CFStringを使って文字列の処理をする場合、文字列の比較はどうするかということで、比較関数を探してみます。

http://developer.apple.com/documentation/CoreFoundation/Reference/CFStringRef/Reference/FunctionGroupIndex.html

を見てみますと、CFStringCompare()というAPIがあることが分かります。以下のような感じで使います。

CFStringRef str1, str2;
str1 = CFSTR("0123");
str2 = CFStringCreateWithFormat(NULL, NULL, CFSTR("%04d"), 123);

if (CFStringCompare(str1, str2, 0) == 0) {
    CFShow(CFSTR("Same"));
}
else {
    CFShow(CFSTR("Not same"));
}


 ちょっとごちゃごちゃしている部分があるので、読みにくいかもしれませんが、CFStringCreateWithFormat()というのは、ANSI Cでいうところのprintf()方式で新たにCFStringの文字列を生成するAPIです。従って、str1とstr2には結果的に同じ文字列が格納されることになるので、比較の結果は「同じ」となるわけです。
 ところで、CFStringに極めて似た役割を持ち、文字列の代わりにバイト列を保持するCFDataというのがあります。

http://developer.apple.com/documentation/CoreFoundation/Reference/CFDataRef/Reference/FunctionGroupIndex.html

にAPIの一覧がありますが、CFStringに比べると極端に数が少ないですね。
 バイト列として保持しているデータを比較したいというケースも、文字列ほどではないにしても当然あるわけですが、その場合どうしたらよいのでしょう?
 「バイトデータを一つずつ取り出して、順番に比較する」? まさかね(笑)。
 実は、CFDataRefで保持しているバイト列同士を比較する場合、CFEqual()というAPIが使えます。ん? 「そんなもの、さっきのところにはなかった」って?
 確かにその通り。では、CFEqual()なんてAPIはどこにあるのでしょう?
 ここにあります。

http://developer.apple.com/documentation/CoreFoundation/Reference/CFTypeRef/Reference/FunctionGroupIndex.html#//apple_ref/c/func/CFEqual

 あれ、このAPI、引数として取るのはCFTypeRefってなってますね。これはいったい何なのでしょう?
 前回の時にちょっと触れたのですが、覚えているでしょうか?

 Derived From: CFPropertyList : CFType

 こんなやつです。
 実は、ここのCFTypeってのがまさにそれなんです。CFDataはCFPropertyListというのを経由して、CFTypeから派生していることになっていますから、CFTypeとしての性質も併せ持っているために、CFEqual()に引数として与えることができるって具合なんです。
 そうだとすれば、考えればお分かりの通り、同じ理屈でCFStringに関しても、CFEqual()を使って比較ができることになります。これを用いれば、ANSI Cのstrcmp()のように「== 0」と、ゼロと比較することで「文字列が同じである」と表すのよりももっと直接的な表現になりますね。

if (CFEqual(str1, str2)) {

 どうでしょうか? 確かに言語がCなので、関数のオーバーライドなどというようなことはできないものの、まさしくポリモーフィズムを実現していると思いませんか?

ニュース・解説

今週の解説担当:小池邦人

Carbon ドキュメント & サンプル & SDK ナビゲーション(2004/07/30)

【開発環境】

株式会社ヒューリンクスが、Xcode上で使用可能なIBMのXL C/C++コンパイラの販売を開始しました。これにより、Mac OS X開発環境としてもうひとつの選択肢が提供されることになったわけで、デベロッパーにとっては大変喜ばしいことです。なにせPowerPCを設計しているIBMのC/C++コンパイラですから、その信頼性の高さについては疑問の余地がないでしょう(長年自社内で使用しているでしょうし)。実は、WWDC2004においても、64ビットコンピューティングのセッションでIBMの技術社がゲストスピーカーとして壇上に上り、このコンパイラについての詳しい解説を行いました。

価格は「IBM XL C/C++ Absoft Fx デバッガ MacOSX」で 107,100です。教育用(学割のこと?)として購入する場合には、ほぼ半額の 58,800です。う〜ん、落ち着いたらどこかの大学の先生か学生になりたいところです(笑)。

http://www.hulinks.co.jp/software/xlc_mac/

【テクニカルドキュメント】

前回から7月30日の期間中、Apple社のDocumentationサイトにはドキュメントがひとつも登録されませんでしたが、デベロッパ向けの読み物として以下の2つの解説が登録されています。

「Simultaneous Development: Blizzard Does Both At Once」(読み物)

http://developer.apple.com/business/macmarket/blizzard.html

「Installing the W3C HTML Validator on Mac OS X」(読み物)

http://developer.apple.com/internet/opensource/validator.html

前回から7月30日の期間中、新規のテクニカルノートはひとつも登録されませんでした。テクニカルQ&Aの方は3つ登録されました。Rendezvous関連の解説です。Rendezvousは商標の関係により、その名称がOpenTalkに変更されると言う噂があります。さてどうなんでしょうか? 個人的意見としては、OpenTalkの方が分かりやすくて良いと思うのですが(笑)。

QA1306「Rendezvous enforces the TXT record format in Panther」
QA1312「Rendezvous service types used in Mac OS X」
QA1302「Updating the TXT record of a Rendezvous service」

http://developer.apple.com/technicalqas/index-rev-date.html

【サンプルソースコード】

前回から7月30日の期間中、Apple社のSample Codeサイトには、新しいサンプルソースコードが2つ登録されました。両方とも新しいバージョンとしての再録です。

「AppleJavaExtensions 」(Java関連)
「SimplePlayThru」(Core Audio関連)

http://developer.apple.com/samplecode/index-rev-date.html

【デベロップメント SDK】

前回から7月30日の期間中、Apple社のSDKサイトには新しいSDKはひとつも登録されませんでした。

http://developer.apple.com/sdk/

MOSAからのお知らせと編集後記は割愛します

MOSA Developer News   略称[MOSADeN=モサ伝]
Apple、Mac OSは米国アップルコンピュータ社の登録商標です。またそのほかの各製品名等はそれぞれ各社の商標ならびに登録商標です。
このメールの再配信、および掲載された記事の無断転載を禁じます。
http://www.mosa.gr.jp/
Copyright (C)2004-2006 MOSA. All rights reserved.