MOSA Multi-OS Software Artists

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

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

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

2005-03-22

目次

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

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

 本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。引き続き、コレクションの抽象クラス「Collection」のプロトコルを覗きながら、コレクションがどんなメッセージを受け付けるオブジェクトなのか、その“正体”を探ってゆきましょう。

 前回、コレクションとブロックの絶妙なコンビネーションで実現されるenumerating(列挙)プロトコルを先に終えたので、その前に飛ばしてしまったarithmeticプロトコルに話を戻します。

 Collectionクラスを選択した状態のブラウザで、arithmeticプロトコルをクリックしてメソッド一覧を見ると、そこには見慣れた二項演算子(二項メッセージセレクタ)が並んでいます。このことは、コレクションの仲間が、まるで数値のように演算操作を受け付けることを意味します。実際に試すとこんな感じです。

#(3 9 8 1) * 4 ” => #(12 36 32 4) ”

 各要素に同じメッセージ(この場合「* 4」)を送ったときの返値を改めて各要素とする新しいコレクションが作られ、それが返値となっています。ただしこの場合、コレクションに送られたメッセージと同じメッセージを、要素が受け付けることが前提となっているので注意が必要です。たとえば次のようなコレクションの場合、第三の要素のシンボル「#eight」は、「* 4」というメッセージをうまく処理できないので例外があがります。

#(3 9 #eight 1) * 4 ” => Error ”

 引数には数値以外にも同じコレクションを与えることも可能です。ただし、レシーバと引数で要素数が一致している必要があります。

#(12 36 32 4) / #(3 9 8 1)  " => #(4 4 4 4) "
#(4 8 12) / (1 to: 3)       " => #(4 4 4) "

 さて、このように引数によって変わる振る舞いを定義したメソッドは、いったい、どんな記述になっているのでしょうか。ちょっと想像してみてください。C++やJavaのように引数の型指定と多重定義が可能なら、想定される引数の型の数だけ関数(メソッド)を多重定義すればよいわけですが、あいにくSmalltalkには、引数の型指定も多重定義もありません。ならば、引数の型を判断して条件分岐…というのが常套ですが、Smalltalkでは別の面白い方法を使っています。

 仮にここで、#(1 2 3)に「* 4」を送信した場合を想定します。このとき#(1 2 3)が起動するのはCollection >> #*メソッドで、その定義はこれです。

Collection >> * arg
   ^ arg adaptToCollection: self andSend: #*

 なんともあっさりしたものですね。引数に対してレシーバ(今は#(1 2 3)。selfに束縛)と、このメソッドを起動するのに用いたメッセージのセレクタ(#*)を引数にした「adaptToCollection: self andSend: #*」というメッセージを送信するひとつの式が記述されているだけです。これでは#(4 8 12)という結果の説明ができないので、このメッセージ送信によって起動する#adaptToCollection:andSend:というメソッドの定義を追ってみましょう。
(記憶力がよく、かつ、目先の利く読者のかたの中には、前々回飛ばしたadaptingプロトコルを思い起こされる向きもあるかもしれませんね。でも、それはいったん忘れてください)。

 システム内の#adaptToCollection:andSend:の定義をブラウズするためには、ブラウザ中段の「implementors」ボタンをクリックしてポップアップするメニューから「adaptToCollection:andSend:」を選択します。すると、よりシンプルな形のブラウザが現われ、上のペインにCollection、Number、Point、Stringが列挙されます。これは、この四つのクラスに#adaptToCollection:andSend:が定義されていることを意味します。

 今は、#(1 2 3)に「* 4」というメッセージを送信したとの仮定ですので、コレクションは改めて、引数の「4」に「adaptToCollection: self andSend:#*」というメッセージを送ることになることに注意してください。結果的に、前述四つのメソッドのうち、Number >> #adaptToCollection:andSend:が起動します。このメソッドの定義は次のようなものです。

adaptToCollection: rcvr andSend: selector
    ^ rcvr collect: [:element | element perform: selector with: self]

 前回、扱った#collect:が登場します。rcvrには、かつてのレシーバである#(1 2 3)が束縛されています。これを念頭に、メソッド本体の式を書き直すとこうなります。

#(1 2 3) collect: [:element | element perform: #* with: 4]

 #perform:with:は第一引数に与えられたパラメータをセレクタに、第二引数に与えられたパラメータを引数にしたメッセージ送信をシミュレートするメソッドです。つまり同式は、再度改めて次のように書き直すことができます。

#(1 2 3) collect: [:element | element * 4]

 一連のメッセージカスケードにより、最初の「#(1 2 3) * 4」が、上の式のように置き換えられ、評価されたと考えても良さそうです。なるほど、これならば#(4 8 12)が返ってくるはずですね。では、引数が4ではなく、#(4 5 6)のようなコレクションならどうでしょう。

#(1 2 3) * #(4 5 6)

 上の「* 4」のときと同様に、「* #(4 5 6)」というメッセージ送信から派生的に生じるカスケードを追ってみてください。これは次回までの宿題にいたしましょう。なお、#with:collect:という、まだ紹介していないメソッドも登場しますが、応用や想像で補うことで解釈は可能なはずです。

バックナンバー:
http://squab.no-ip.com:8080/mosaren/

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

 承前……とか偉そうに書き始めたけど前回どこまでいったんだっけ?
 そうそう、Nibファイルで作成した(Interface Builderは定義だけでなくインスタンシエイトまでやることに注意してちょうだい)オブジェクトがメモリ上に場を与えられ、IBOutletやIBActionで示される相互の関係づけが完了すると、そのオブジェクトにはawakeFromNibというメッセージが送られる、というところまでだった。覚えてますか?
 ほんで、今回考えますと予告しておいたのが「awakeFromNibメッセージはどのオブジェクトに最後に送られるのか」。ひらたく言えばNibファイルの中身のオブジェクトはどんな順番でメモリ上に配置されるの? で、その最後はどれ? ということである。

 ……ほんとのことを言えばこれ、ここで書いてしまわないで、とにかくオブジェクトをたくさん作り、それぞれがawakeFromNibを受け取ったときに「はいはいはい、オレオレオレ、無事にawakeFromNibを受け取りました!」と出力させる、みたいなテストプログラムを作って実行してみて欲しいんだが……これ、実はわかんないんである。
 わかんない、ぢゃひどいか(笑)。
 正確に言うと、オレがやってみた限りにおいてはawakeFromNibメッセージが送られる順番に、なんら規則は見出せなかった。ある時はタラオバンナイ、ある時は手品好きの気障な紳士……ぢゃないけど、ちょっとNibファイルをいじるだけでその順番がコロコロと変わってしまう……。いや、変わったり変わらなかったりするんである。いつも変わるよりタチが悪い。
 具体的にどういうことかというと、AというオブジェクトがBというオブジェクトにIBOutletとして連結されているとすると、BにawakeFromNibが来たとき、BからAにアクセスは可能である。しかしその時点で、既にAにawakeFromNibが送られているかどうかはわからない。

 そもそもIBOutletは2つのオブジェクトが互いを相互にコネクトすることも可能なのだ。その場合、当然ながらどちらか片方が先にawakeFromNibを受け取るわけなので、「あるオブジェクトがawakeFromNibを受け取ったときに、そっから参照しているオブジェクトが皆awakeFromNibを受け取り済みである、というのはある種の不可能ごとなんである。
 言い換えれば、そういう状況を前提としている処理をawakeFromNibを受け取った時点で行なうように書いてはいけないのである。動かないから? そうぢゃない。動いちゃうこともあるからなおさらいけないのだ、わかるよね?

 で、このジレンマを解決するため、ようやくNSApplicationの出番が来る。Nibファイルから全てのオブジェクトを読み込んでメモリ上に配置し、そのひとつひとつにawakeFromNibを送りつけてそいつらなりの初期化を済ませると、NSApplicationは自分のDelegateに、applicationDidFinishLaunching: というメッセージを送ってくれるのだ。読んで字のごとし、「アプリケーションの起動に関する全ての処理が終わりました」ということなので、上に挙げたような前提が必要な処理に関しては、ここでNSApplicationのdelegateからそのオブジェクトにメッセージを発行すればOKとなるわけだ。
 やれやれ、この辺、わかってみれば簡単なことなんだけど説明するとナガナガとなっちまうなぁ。次回こそホントにNSApplicationの最後、「アプリケーションが終了するとき」のコトについて、これまた使用頻度の高いであろう初期設定値の初期化と保存に搦めて説明する。……この説明がまた2回に渡ったりして(汗)。
(2005_03_17)

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

UNIXとしてのMac OS X
〜Perlについて(10)〜

 こんにちは、高橋真人です。
 前回は文字列の中に変数を埋め込むお話をしましたが、シングルコーテーションで展開されないのは実は変数だけではありません。
 今まで書いてきたコード例で、出力の末尾に改行を加えなかったのにはこの辺の含みがあったのです。

print ‘Hello world¥n’;

 こんなコードがあった場合、出力は、

Hello world¥n

とそのままで、当然のことながら末尾は改行されません。これがPerlなのです。
 で、そうなると文字列を出力する場合には

print “Hello world¥n”;

とダブルコーテーションを使って書けばいいわけですが、数字などをそのまま出力するケースでは、

print 256 …… ?

とやったあとにどのように改行を付加すればよいのでしょうか?
もちろん、

print “256¥n”;

とやれば、いいじゃないかと思われるかもしれません。それは確かにその通りです。ですが、もし数字の部分が計算式だったらどうします?

print 128 * 2 …… ?

 さすがにダブルコーテーションで囲っても、計算式までは展開してくれるわけではありませんから、ちょっと困ってしまいますね。

 以前「print演算子はリストコンテキストを要求する」とお話ししたのを覚えておいででしょうか? つまり、こういう場合にはリストとして改行をくっつけてしまえばいいんです。

print 128 * 2, “¥n”;

と、こんな感じです。
 こういうやり方ができるとなりますと、当然文字列に対してもカンマでつなぐということができるわけです。

print ‘Hello world’, “¥n”;

 「一体、こんなことをするのに何の意味があるのだ?」と思われる方もおいでかもしれません。それならば、たとえばこんなケースはどうでしょう。$という記号をスカラー変数の意味ではなく使いたい場合がありますよね。

print “The book is $100.¥n”;

今まで説明してきませんでしたが、Perlでは変数の宣言は必須ではありません(宣言を必須にする設定も可能です)。そのため変数は「登場したところから」使えるようになるのですが、今回のケースのようにいきなり値を設定することなしに値を読み出そうとしますと、これはエラーになってしまいます。
 実際に上記のコードを実行すると、

The book is .

と、まるで$100という変数には「何も値が入っていない」かのように出力されますが、Perlにおいて未初期化の変数は「undef」という値に評価されることになっているのです。
 結果的にundefが文字列として解釈されるとカラ文字列となるため、上記のような出力結果になるわけです。
 また、Cでやるようにいわゆるエスケープ文字を直前に置いてやる(¥$)ことでも望みの結果を得ることはできますが、Perlの設計思想から考えて、こういう「コードを読みづらくする要素」を余り使わずに記述できるところもメリットだと思うので、あえてシングルコーテーションを使って、特殊記号となり得る文字も「見た目のまま」使うことができる方法をご紹介しました。

ニュース・解説

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

Carbon ドキュメント & サンプル & SDK ナビゲーション(2005/3/4)

【開発環境】

随分と前から、IBMがPC970のDual Core版であるPC970MPと呼ばれるCPUを開発しているという噂が流れていました。つまり、PowerMac G5にこのCPUを2つ搭載すれば、同時に4CPUを稼働させることが可能なQuad PowerMac G5に化けるわけです。さて、近頃この噂が再熱しております。その火元は、Apple社が開発用ツールとしてデベロッパーに提供している「Computer Hardware Understanding Development Tools(CHUD)」です。つい最近、このツールの最新バージョンv4.1.0が関連サイトに登録されたのですが、その中の「Processor」環境設定のCPU稼働チェックの空きスペースが4つに増えていたのがその発端でした。その後、「何かを探すことには絶大な能力を発揮する」多くのMacデベロッパー達により、CHUDに隠されていた4CPUマシン登場の物件的証拠が次々と暴かれていきました。

さすがに焦ったのか、Apple社は数日後にCHUDを v4.1.1に差し替え(旧バージョンは削除)、そうした証拠もすべて隠蔽してしまいました。例えば、最新版ではCPUチェックのスペースが3つに(笑)変更されております(わざとらしい…)。そうこうしているうちに、今度はIBMのサイトに、何かの手違いでPC970MP CPUの熱対策の解説文章と「Using Thermal Diodes in the PowerPC970MP(R) Processor」という技術解説ドキュメントが登録されてしまいました。Apple社からクレームが入ったのでしょうか? すかさず、次の日にはこちらも削除されましたが、Dual Core CPUであるPC970MPが存在しているのは確かな事実のようです。

試作4CPUマシンのテスト用として「特別版」CHUDを用いていたとしても、それをそのまま一般に公開することはないでしょう。また、970MPが実際に存在することも明らかになったわけですから、間違いなく近々にQuad PowerMac G5は登場すると思われます。問題はその発表時期ですが、何やら、現在のMac OS X 10.3では4CPUには対応していないという話もあり、そこから推測すると、この新型のQuad PowerMac G5はMac OS X 10.4(Tiger)の発表と同時に登場するかもしれません。もし、もう少し発表まで時間が必要であるならば、その場はWWDC2005の基調講演と言うことになるでしょう。もっともっと高速のPowerMacの登場を望む筆者は、新PowerMac G5の発表を楽しみに待ちたいと思います(お金を貯めて…)。

Apple社が、WWDC2005への参加を希望する学生を対象にした「ADC Accepting WWDC Student Scholarship Applications」を開始しました。指定されたテーマでレポートを書いてApple社へ送れば、WWDC2005への参加費用が免除される可能性があります。希望者の学生さんはぜひチャレンジしてみてください。

http://developer.apple.com/wwdc/students/index.html

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

前回から3月18日の期間中、Apple社のDocumentationサイトには新規ドキュメントがひとつも登録されませんでした。しかし、デベロッパー向けの読み物の方は2つ登録されています。「OsiriX Brings Collaboration to Medical Imaging」は、医療用のDICOM Voxelビューア(フリーウェアとして提供)の「OsiriX」の紹介です。この医療用アプリケーションは、CT撮影で得られたDICOM画像をボクセル化して表示するなどの専門的な機能の他に、Mac OS X特有の様々な機能(iPod、.Mac、QuickTime VRなど)を医療現場でうまく活用できるように工夫されています。「Tiger Developer Overview Series: Developing with Core Image」の方は、前号の木下さんの解説を参考にしてみてください。

「OsiriX Brings Collaboration to Medical Imaging」(読み物)

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

「Tiger Developer Overview Series: Developing with Core Image」(読み物)

http://developer.apple.com/macosx/tiger/coreimage.html

前回から3月18日の期間中、新規のテクニカルノートはひとつも登録されませんでしたが、新規テクニカルQ&Aの方は2つだけ登録されました。QA1415では、自力で開発したMovie Export ComponentをFinal Cut Proで認識させるための「呪文」が、QA1404の方では、アドレスブックへのCustom Propertyの正しい加え方のサンプルソースコードが紹介されています。

QA1404「Crash in ABAddPropertiesAndTypes」
QA1415「Movie Export Component – How to ensure Final Cut Pro recognizes your exporter」

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

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

前回から3月18日の期間中、Apple社のSample Codeサイトには、新しいサンプルソースコードが7つ登録されました。「QuartzShapes」と「SampleUSBAudioPlugin」のみが新規のサンプルで、それ以外はマイナーな修正とバージョン変更です。

「AudioBurn」(Cocoa関連)
「DataBurn」(Cocoa関連)
「ComplexPlayThru」(CoerAudio関連)
「QDCocoaComponent」(Cocoa関連)
「SampleFilterScheme」(Kernel関連)
「QuartzShapes」(CoreGraphics関連)
「SampleUSBAudioPlugin」(USB関連)

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

【デベロップメント SDK】

前回から3月18日の期間中、Apple社のSDKサイトには新しいSDKがひとつも登録されませんでしたが、CHUDの最新版v4.1.1がPerformance and Debugging Toolsサイトに登録されています。v4.1.1の登場数日前に、例の(笑)v4.1.0が登録されたのですが、そのバージョンは既にFTPサーバから削除されています(幻のバージョンと化しました)。

「Computer Hardware Understanding Development Tools(CHUD)4.1.1」

http://developer.apple.com/tools/performance/

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

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