MOSA Multi-OS Software Artists

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

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

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

2004-08-24

目次

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

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

 本連載では、名前はよく耳にしていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回は、通常のプログラミング言語では構文として用意されているループや条件分岐が、すべてをメッセージ式のみで表わそうとするSmalltalkにおいて、どのように実現されているかを解説します。

(3 > 4) ifTrue: [5] ifFalse: [6] “=> 6 ”

 この式は「3」が「4」より大きければ「5」、そうでなければ「6」を返します。もちろん、3は4より大きくないので、ブロック[6]の評価結果である「6」を返すはずです。この式はprint it(cmd-P)で実際に動作を確認できるので試してみてください。ここで、式「3 > 4」は、レシーバ「3」にメッセージ「> 4」を送って「false」を返します。なお、メッセージ式において、単項メッセージは二項メッセージに、二項メッセージはキーワードメッセージに優先して評価されます。したがって、(3 > 4)の括弧は、ここでは読みやすくするために付けましたが、実際には不要です。

3 > 4 ifTrue: [5] ifFalse: [6] “=> 6″

と書いても問題なく評価されます。同じくキーワードメッセージに優先される単項メッセージも同じです。

(3 isZero) ifTrue: [5] ifFalse: [6] “=> 6 「3 isZero」は3が0ならtrue”
3 isZero ifTrue: [5] ifFalse: [6] “=> 6 括弧は不要”

しかし、

(3 isDivisibleBy: 4) ifTrue: [5] ifFalse: [6] “=> 6 ”

のように、レシーバであるtrueやfalseを産生する式が、キーワードメッセージの場合(あるいは、もっと複雑な式の場合)は括弧は必要です。たとえば上の例で、もしこの括弧がないと、

3 isDivisibleBy: 4 ifTrue: [5] ifFalse: [6]

となり、3への「isDivisibleBy: 4 ifTrue: [5] ifFalse: [6]」というメッセージ送信と解釈されてしまいます。当然、#isDivisibleBy:ifTrue:ifFalse:などというセレクタは登録されていないのでこうしたコードがあっても、例外が生じて処理は中断しますし、そもそも評価時(メソッドならコンパイル時)に警告が出るので、ミスしたことには容易に気付くことができるはずです。

 話を戻します。前式は、(3 > 4)が常にfalseを返すので、

false ifTrue: [5] ifFalse: [6] “=> 6 ”

と書き換えても結果は同じです。レシーバ「false」に送られるメッセージ「ifTrue: [5] ifFalse: [6]」は、#ifTure:ifFalseというセレクタ(メソッド名)と、[5]と[6]という2つのパラメータからなります。同じメッセージを、試しにtrueに送ってみましょう。

true ifTrue: [5] ifFalse: [6] “=> 5 ”

今度はブロック[5]の評価結果である「5」が返ります。

 ここで条件分岐について、もう少し掘り下げて考えてみることにします。メッセージ「ifTrue: [5] ifFalse: [6]」によって起動される#ifTrue:ifFalse:というメソッドの中身はどんなものか、想像してみてください。オーソドックスには、レシーバがtrueなら第1パラメータとして与えられた真時ブロックを、falseなら第2パラメータの偽時ブロックを遅延評価して結果を返値として返す…というような手続きを記述した関数(メソッド)を用意すればよいように思います。しかし、Smalltalkではこれとは別のアプローチをとっています。

Smalltalkでは真偽値(true、false)もオブジェクトです。これは、それぞれが「ifTrue: [5] ifFalse: [6]」というメッセージを受信できることからもお分かりいただけると思います。trueはクラスTrueの、falseはクラスFalseの、それぞれ唯一のインスタンスです。

メソッド#ifTrue:ifFalse:は、実は、クラスTrue、クラスFalseに別々に定義されています。Smalltalkプログラマのあいだでは、クラスTrueに定義されているメソッド#ifTrue:ifFalseを表わすのに「True >> #ifTrue:ifFalse」のように書く習慣があるので、これに従うと、#ifTrue:ifFalseという名のメソッドは、True >> #ifTrue:ifFalseと、False >> #ifTrue:ifFalseの2つが存在する…ということになります。

trueはメッセージ「ifTrue: [5] ifFalse: [6]」を受けると、True >>#ifTrue:ifFalse:を起動し、falseはFalse >> #ifTrue:ifFalse:を起動します。True >> #ifTrue:ifFalse:には、第2パラメータを無視し、第1パラメータとして渡されるブロックを評価した結果を返す手続きが記述されています。False >> #ifTrue:ifFalse:には逆、つまり、第1パラメータを無視し、第2パラメータであるブロックを評価した結果を返す手続きだけが記述されています。実際に、True >> #ifTrue:ifFase:、あるいは、False >>#ifTrue:ifFalse:のソースコードを見て、実際にそうなっているか確認してみましょう。

適当な場所に「ifTrue:ifFalse:」と入力後、選択してからimplementors of it(cmd-M)します。すると、図に示すような2ペインのウインドウが現われるので、上のペインからTrue ifTrue:ifFalse: {controlling}、あるいは、False ifTrue:ifFalse: {controlling}と書かれた選択肢をクリックして選択すると、下のペインにそれに対応するメソッドのソースを呼び出すことができます。

[fig.A]#ifTrue:ifFalse:メソッドのソースを閲覧するためのウインドウ
http://squab.no-ip.com:8080/mosaren/uploads/07a.png

[fig.B]True >> #ifTrue:ifFalse:のソースコード
http://squab.no-ip.com:8080/mosaren/uploads/07b.png

[fig.C]False >> #ifTrue:ifFalse:のソースコード
http://squab.no-ip.com:8080/mosaren/uploads/07c.png

 Smalltalkのメソッドのソースコードの読み方をここで簡単に説明しておきましょう。太字で書かれた1行目、

ifTrue: trueAlternativeBlock falseAlternativeBlock

は、メッセージパターンと呼ばれるもので、このメソッドを呼び出すためのメッセージの記述方法を示したものです。メソッド名(セレクタ。ここでは#ifTrue:ifFalse:)とパラメータ変数(trueAlternativeBlockとfalseAlternativeBlock)の宣言も兼ねています。2行目と3行目にはコメントとしてこのメソッドの説明が書かれています。

3行目が、短いですがメソッド本体のソースコードです。「↑」は「^」(ハット)で入力できる記号で、メソッドの終了とそのときの返値を明示的にするときに使います。ちなみに返値を明示的にしないときはself(レシーバ自身)が返値として返ります。なお、Smalltalkには返値のない関数(メソッド)というものはありません。

#ifTrue:ifFalse:メソッド本体のコードを改めて見ていただくと、受け取ったブロックのうち一方を単純に評価(メッセージ「value」を送信)して値を返しているだけであることが、はっきりと見てとれると思います。条件分岐をメッセージ送信で表現することも特殊なら、その実装方法も特殊で、しかもとてもシンプルにそれを実現していることはたいへん興味深いですね。(実はこの話には“大きな嘘”があります。しかし、コンパイラの挙動やバイトコードに言及する必要があるので、またの機会に…)

次回は、サンプルプログラムに話を戻して、描いた絵を保存する機能拡張を施します。

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

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

 承前、ということになる。前回はC++の多重継承が「空飛ぶコーモリはケモノでもあるがトリでもある」としちゃいがちな機構であり、ヘタに使うと(言うまでもないがうまく使えば問題はない、というかそもそもは「うまく使われる」ためにあるんだからね)スパゲティ・プログラムのOOP版……うまい比喩が思いつかぬが人知を超えた実験料理みたいなものになっちまうという話を書いた。これに比べて多重継承を許さないObjective-Cはそういう余地がないのでオレはこっちの方が好きである、と。
 ここでOOP理解はイマイチながらそれなりに頭のスルドいあなたは当然以下のような疑問を持ったはずである。すなわち、
 「トリとケモノを多重継承せずにどうやってコーモリに空を飛ばせっつうのだ?」
と、いうことですね。今回はその話。

 確かにコーモリもトリも空を飛ぶ。だけどそれを言ったらセミだってミツバチだって飛行機やヘリコプター、スーパーマンだって銃弾だって飛ぶんである。ミミズだっておけらだってあめんぼだってみんなみんな生きているんだトモダチなんである。ミミズとおけらは飛ばないけど……。
 つまりはこういうことだ。「飛べる」という能力はトリだけの専売特許ではない。トリというクラスに固有の(ゆえにそれを継承するにはサブクラスするしかない)能力ではなく、クラス横断、複数のクラスにまたがって保持される類いの能力である。そしてその「飛行能力」というモノ自体はなんらの実体を持たない抽象的な概念である、わかりますか。
 C++やJavaなどの言語にはこうした抽象概念を扱うための抽象クラス(abstract class)という仕組みが用意されている。例えば「飛べる」という抽象クラスは以下のように定義する。

class ItCanFly {
/*  variables declaration it needs... */
public:
  virtual void fly(void) = 0;    /* pure viratual function */
}

 関数 fly() の定義部分にコメントしているが、この例のように「=0」(こいつを純粋指定子という)をくっつけて宣言した関数を「純粋仮想関数」といい、この純粋か相関数を一個でも持つクラスはそのまま自動的に抽象クラス、ということになってるんだが、そういう用語なんか暗記しなくてもいい(実はオレもここの用語は参考書で確認しながら書いた)。それよりこの抽象クラスというものの、文字通り「抽象性」というものをよっく味わってもらいたいのだ。
 他のことに関しては通常のクラスと同じでありながら、このクラスの使用にはひとつだけできないことがある。それは「直接このクラスのインスタンスを生成できない」ということ、つまりこの仕組みは例えば「飛べる」のような純粋に抽象的な能力を「多重継承を」を使って個々のオブジェクトに付与するためにあるのだ。以下に「コーモリを『飛べるケモノ』とする具体的な定義」を示しておく。

class Bat : public Animal,  ItCanFly {
/* variables declaration it needs... */
public:
  void fly(void);    /* You must declar this function concretely */
}

 そしてこのコーモリのように抽象クラス「飛べる」を継承したクラスは抽象クラスの持つ純粋仮想関数を具体的に定義しなければならない。上で見たようにトリも飛行機もスーパーマンもそしてコーモリも飛ぶが、その方法はいろいろであり、それを記述する責任はサブクラス側にゆだねられている。

ここまで説明すれば「コーモリを飛ばすためにトリを多重継承させる」ことの愚がわかってもらえたと思う。たまたまコーモリはトリと同じように「羽ばたいて」飛ぶが、やってることは「コーモリを飛ばすためにスーパーマンを多重継承しちゃう」のと同じことなんだってば……。え、それがバットマンだって? バットマンって飛べたっけ?
(2004_08_14)

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

UNIXとしてのMac OS X

〜導入のお話〜

 こんにちは、高橋真人です。さて、思いつくままに駄文を書き連ねてきたこの連載ですが、いつの間にか50回を数えることになりました。
 区切りのよい数を迎えたこととは全く関係ありませんが、かねてお話ししていたようにオブジェクト指向に関するお話に関してはいったんおしまいにし、今回からは少し切り口を変えてちょっとした役に立つ(かもしれない)小ネタをいくつか紹介していきたいと思います。とはいえ、私の中にためてきた小ネタで果たしてどのくらいの期間持つのかは皆目検討が付きませんので、再び突然の路線変更などということもあるかもしれません(笑)。
 さて、当面は今回の表題にもうたっているように、Mac OS XのUNIX的な側面に関して注目してのお話を展開していこうと思っています。
 ただ、UNIX的な側面ということに関しても、最近ではMac OS XのUNIX面について解説している書籍も増えてきましたし、雑誌などでも特集が組まれることも多いので、それと同じではあまり面白くありません。それに、LinuxやOPENSTEPの環境でバリバリにやってきた方々に役立つような情報は到底私に提供できるわけもありませんので、ここはひとつ「プログラミング指南」らしく、プログラミング初心者の方にメリットのありそうな情報という観点で行きたいと思います。

「MacがUNIXになる」。そんな話を聞いた数年前、私はかなり興奮したのを覚えています。Macにある程度慣れたころから、「そのうちUNIXに手を出してみたい」と思って、Linuxで遊ぶためにDOS/Vマシンを購入した(新しいマシンを買ってしまったため、Linuxがまだ対応しておらず、インストールの途中で撃沈)ことさえあったくらいですから、わざわざ新たにマシンを用意せずとも「Macで何でもできる」という状態は私にとってはまさに夢でした。
 もっとも、当時はまだユーザーとしての視点しかなく、プログラミング的にどのようなメリットがあるのかなどということは考えてもみませんでした。ですが、最近になって、仕事で特にネットワークがらみの仕組みが必要になることが多く、改めてネットワークプログラミングについて勉強すると、この辺のメリットを実感することは多いのです。
 たとえばUNIX向けとうたってある本であれば、特にMac OS X対応となっていない本であっても、掲載されているサンプルソースを打ち込んでみるとほとんど修正も必要なく動作したりすることは多く、そんな時にこそ「夢が叶ったなぁ」と実感するのです。
 このように夢の環境が身近なところにあるにもかかわらず、単に従来のMac OSの延長として使っている人がことのほか多いようです。もちろん安定性だとかプリエンプティブマルチタスクという、さんざん強調されてきた特徴も、生産性の貢献という意味で大きな価値があることは疑いのないところです。
 ですが、PostgreSQLなどのちまたで人気のオープンソースのデータベースがネイティブで動作するとか、ApacheやPerl、Ruby、PostfixだのといったLinuxの世界でもとても人気のある製品が最初から標準機能として備わっているという、とても「おいしい」状態を興味を持たずに放っておくのももったいない話だと思うのです。
 そういう人たちの中に、こんなことをおっしゃる方がいます。
 「確かに、世の中にはUNIXという切り口での解説記事や書籍が出ていて、前書きには『Mac OS Xでも動作するので、必要な部分を読み替えろ』と書いてある。しかし、いざ実践しようとするとその読み替えをどのようにすればよいのかが皆目検討つかない。また、書き込み権限がどうだのと、インストールすらままならない場合もある」
 確かに、慣れない人にとってUNIXの文化は難しい部分もあるようです。かなり歴史の長いOSですから、「知っている人しか知らない」状態の知識というものも多く、そこが初心者にとっては敷居を高くする要因であるのかもしれません。
 そんなわけで、皆さんと同じ「普通のMacユーザー」状態からスタートし、試行錯誤しながらも現在ではMacのUNIX機能をそれなりに享受することのできている私が自分の経験から取得したワザをいくつかご披露できれば、と思っているのです。

ニュース・解説

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

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

【開発環境】

Apple社からXcode 1.5の正式版が発表されました。すべての開発環境を含んだ「Xcode Tools 1.5」は、ADCメンバーサイトからダウンロードすることができます。新しい機能や改良点は、Xcodeを最初に起動した時に表示されるRelease Notesを読めば確認できます(Helpメニューからも表示可能)。Xcode Tools全体の詳細については、以下のToolsサイトを参照してください。ちなみに、Interface Builderはv1.2から何も変化がありませんでした(涙)。ちゃんと開発は継続しているのでしょうか?

http://devworld.apple.com/tools/xcode/

Metrowerks社のダウンロードサイトに「CodeWarrior Development Studio for Mac OS, Version 9.3 Update」が登録されました。さっそく筆者の開発環境もv9.3へとアップデートしてみました。開発中の色々なプロジェクトを再コンパイル&リンクしてみたのですが、今のところ問題は発生していません。Apple社の最新の開発環境とv9.2の組み合わせでは、プロジェクトにcrt1.oを加えているとリンクが正常に終了しない問題が発生していましたが(mwcrt1.oの方は大丈夫)、v9.3ではそれもちゃんと改善されています。

WWDC2004ではブースも出展していなかったMetrowerks社ですが、まだMacintoshユーザは忘れられていなかったようです(笑)。コンパイラのG5への最適化を含め、これからもちゃんとしたサポートの継続を望みたいところです。v9.3 Updaterを入手するには、以下のMetrowerks社のダウンロードサイトへ入り、「Updates and Patches」のリストから「CodeWarrior for Mac OS 9」(Mac OS 9という意味ではなくバージョン9の意味)を選択してください。v9.3 Updaterの容量は112M Byteもありますので、ダウンロード時間には注意しましょう。

「CodeWarrior Development Studio for Mac OS, Version 9.3 Update」

http://www.metrowerks.com/MW/download/default.asp

ソフトウェア・アップデートから「Java 1.4.2 Update 1」がダウンロードできるようになりましたが、それに対応してADCメンバーサイトに「java142update1tools」が登録されました。また、Apple社のReleaseサイトには、以下の2つのドキュメントが追加されています。

「Introduction to Java 1.4.2 Release Notes」(PDFあり)

http://developer.apple.com/releasenotes/Java/Java142RN/index.html

「Introduction to Java 1.4.2 Update 1 Release Notes」(PDFあり)

http://developer.apple.com/releasenotes/Java/Java142RNUpdate1/index.html

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

前回から8月20日の期間中、Apple社のDocumentationサイトには新規ドキュメントが9つ登録されました。加えて、デベロッパ向けの読み物として以下の3つの解説が登録されています。

「Jar Bundler」(PDFあり)
「Plug-ins」
「Mac OS X Assembler Guide」(PDFあり)
「Remote Debugging in Xcode」
「Streams」
「Text System User Interface Layer」(PDFあり)
「Xcode Build System」
「Coding Guidelines」
「Transferring Data With URL Access Manager」(PDFあり)

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

「Carbon Pasteboards: Enhancing Data Sharing」(読み物)

http://developer.apple.com/carbon/pasteboards.html

「Universal Access: Computers That Everyone Can Use」(読み物)

http://developer.apple.com/accessibility/universalaccess.html

「Introducing Xcode 1.5: Improving Speed and Workflow」(読み物)

http://developer.apple.com/tools/xcode/reviewxcode.html

前回から8月20日の期間中、新規のテクニカルノートは2つ登録されましたが、テクニカルQ&Aの方はひとつも登録されませんでした。「Kernel Core Dumps」は、Mac OS X 10.3でカーネルパニックやハングアップが発生した時に、リモートでコアダンプを実行することでカーネルの状態を調べる方法が解説されています。

TN2118「Kernel Core Dumps」
TN2110「Identifying Java on Mac OS X」

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

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

前回から8月20日の期間中、Apple社のSample Codeサイトには、新しいサンプルソースコードが5つ登録されました。「CarbonSketch」は、QuickDraw APIからQuartz 2D APIへの移行を促すための例題としてWWDC2004のセッションでも紹介されていました。しかし、Apple社はこのレベルの例題を提示しておけば移行が可能だと本当に思っているのでしょうか(笑)。多くのQuickTime APIがいまだにGWorldベースなんですけどねぇ?

「SpellingChecker CarbonCocoa Bundled」( Carbon関連)
「BackgroundExporter」(QuickTime関連)
「CFFTPSample」(CFNetwork関連)
「CarbonSketch」(Quartz 2D関連)
「ComplexPlayThru」(CoreAudio関連)

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

【デベロップメント SDK】

前回から8月20日の期間中、Apple社のSDKサイトには新しいSDKはひとつも登録されませんでしたが、Mac OS X 10.3.5用の「Kernel Debug Kit」が登録されています。また、Darwinサイトにはプレビュー版 Mac OS X 10.4(Tiger)とMac OS X 10.3.5用の最新ソースが登録されました。

「Kernel Debug Kit 10.3.5」

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

「WWDC 2004 Developer Preview (Darwin 8.0b1 Source Code)」

http://www.opensource.apple.com/darwinsource/WWDC2004/

「Darwin 7.5 Source Code」

http://developer.apple.com/darwin/

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

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