MOSA Multi-OS Software Artists

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

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

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

2005-01-25

目次

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

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

 本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。定番オブジェクト解説の三回目は「ブロック」です。

 ブロック(a BlockContext)は手続きをオブジェクトとして取り扱えるようにしたものです。制御構造構文を持たないSmalltalk言語では、苦肉の策…というわけではないのですが、ブロックをパラメータに添えたメッセージ送信を行なうことで、制御構造を実現します。

1 < 2 ifTrue: [3 + 4] ifFalse: [5 - 6] "=> 7 ”

 特別な制御構造を持たず、ブロックとメソッド(関数)の組み合わせで同様の機能を提供するということは、Smalltalk言語においては、ユーザーがその必要に応じて、自由に制御構造を創造し言語機能を拡張できることを意味します。

 ブロックは、通常の処理を大括弧「[ ]」で括ることで表現できます。

3 + 4 “=> 7 ”
[3 + 4] “=> a BlockContext ”

 通常のオブジェクトと同様に、メッセージのレシーバになったり、変数に束縛(代入)したり、パラメータ(引数)として渡したりできます。制御構造的なしくみでは、最後の性質を利用しているわけです。

| block |
block _ [3 + 4].
World findATranscript: nil.   "トランスクリプト呼び出し"
Transcript
   cr; show: 7 = block;       "=> false        "
   cr; show: block = block;   "=> true         "
   cr; show: block class      "=> BlockContext "

 処理を実行するためには改めてメッセージ「value」を送る必要があります。

[3 + 4] value “=> 7 ”

 関数のように引数(パラメータ)を持たせることも可能です。パラメータを束縛する変数を「ブロック変数」と呼び、ブロック表現の先頭に列挙して宣言します。たとえば、パラメータを二乗して返すブロックは、次のように表現します。

[:x | x * x]

 ブロック変数を宣言するとき、その頭にはコロン「:」を付けます【註1】。ブロック変数の宣言が終わったら「|」を置いて、ブロック本体の処理と区別します。ブロック変数が複数あるときは、スペースで区切って列挙します。

[:x :y | x + y]

 処理を実行するときは「value」ではなく「value: arg」や「value: arg1 value: arg2」を使います。なお、ブロックの持つブロック変数の数と、評価時に与えるパラメータの数は一致していなければいけません。

[:x | x * x] value: 3               "=> 9 "
[:x :y | x + y] value: 3 value: 4   "=> 7 "
[:x :y | x + y] value: 3
   "=> Error: This block requires 2 arguments. "

 #value:value:value:value:、つまりパラメータが四つのブロック向けのものまで用意されていますが、追いつかないときは、#valueWithArguments:でパラメータを配列に収めた状態で渡すこともできます。

[:x :y | x + y] valueWithArguments: #(3 4) “=> 7 ”

 余談ですが、パラメータの数を動的(実行時)に知りたいときは、メッセージ「numArgs」を送ればブロック自身が答えてくれます。

[3 + 4] numArgs “=> 0 ”
[:x | x * x] numArgs “=> 1 ”
[:x :y | x + y] numArgs “=> 2 ”

 ブロックは無名の関数、あるいは、どのクラスにも属さない無名のメソッドのように考えると理解しやすいことがあります。LISPに通じておられるかたは「ラムダ式に相当する」と言えば、ピンと来るはずです。【註2】

[:x :y | x + y]
(lambda (x y) (+ x y))

註1:このコロンは、メソッド定義におけるメッセージパターン(一行目)において、キーワードがない状態を想定してその書式を模したものだと言われています。実際、こうした書き方はあまり推奨されていませんが、メソッド定義のメッセージパターンと同じように書くこと、つまり、ブロック変数とコロンの間にスペースを入れることも許されています。

[:x :y | x + y] ” OK ”
[: x : y | x + y] ” OK ”
[: x: y | x + y] ” NG ”

註2:ただし、Squeakは古典的なSmalltalkシステムであるため、ブロックがきちんとしたクロージャになっていません(ブロック内に独自のテンポラリ変数が持てず、テンポラリ変数を定義しても外部から自由にアクセスできてしまう。つまり“クローズ”してしない)。したがって、再帰や(疑似)並列処理には使えなかったり、使えても、いろいろと注意する必要があります。なお、最新のSmalltalkであるVisualWorksやANSI準拠のSmalltalk言語処理系では、この点は改良されていて、ブロックはクロージャとして問題なく使用できます。

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

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

 ならば代案を出せと言われるとオレとて困ってしまうのだが、NSApplicationというクラスはあんまり名前がよろしくないと常々思っている。とにかく誤解されやすい名前なのである。
 以前、オブジェクト指向プログラミングについて解説した際に、一つの「アプリケーション・プログラム」を人体に喩え、その構成要素であるヒジ、ヒザ、眼球、そして懐かしいランゲルハンス島などをそれぞれ独自の機能/メソッドを内包するクラスになぞらえて説明した。……いや、覚えていないヒトもいるだろうけどしたんだよ。
 で、NSApplicationというクラスの問題は、上の喩えをまんま食らってこのクラスがヒジやヒザや眼球やランゲルハンス島をその構成要素として抱え込んだ「アプリケーション・プログラム」のヒナ型だと理解しちゃうヒトがいることなんである。
 ……言い方が難しいかな。具体例を出すと、あなたが例えば「MOSAEdit」とかいう名前のテキストエディタをプログラミングしたとする。するとオブジェクト指向プログラミング初心者は、その「MOSAEdit」というアプリケーション・プログラム全体が、包括的にNSApplicationというクラスのインスタンスである、と思ってしまいがちなんである。で、そう考えるといろいろなことがワカリにくくなっちゃうんだよ。

 基本から行こう。XcodeでCocoaアプリケーションのプロジェクトを作ると、ファイル「main.c」の中身はこんな風になってる。

  int main( int argc, const char* argv[] ) {

      return NSApplicationMain( argc, argv );
  }


 この「NSApplicationMain() というCの関数(気をつけて、これは単なるCの関数である)は次のことを行なう。

 1. NSApplication クラスのインスタンス(グローバル変数のNSAppとしてアプリケーション内のどこからでも参照できる)を生成する。
 2. アプリケーションのメインNibファイルをロードする(どれがメインNibファイルかは「info.plist」に定義されている)。
 3. 1で作ったインスタンスに「run」メッセージを送って「run loop」をスタートさせる。

 注意して欲しいのは1と2のトコ。つまり1でNSApplicationのインスタンスが生成されても、その中にNibファイルで定義されているウィンドウとかメニューとかのインスタンスは含まれてないのである。
 それではNSApplicationとはなんなのだろうか。……比喩としてはちと苦しいんだが、人体で言えばそれは「感覚器」と「神経系」を合わせたようなモノである。上の3の「run」メッセージを受け取ると、NSApplicationのインスタンスは「run loop」を開始する。具体的には各種入力ソースをポーリングしてまわり、なにか処理する必要のある事案が発生したらそれを処理すべきオブジェクトにその案件を渡す。受け取ったオブジェクトがその案件を処理することで、初めてそのアプリケーション・プログラムは期待される「機能」を全うできる。NSApplicationはアプリケーション・プログラムの「受付窓口」みたいなものと言えば解りやすいだろうか。

 では次回から、NSApplicationの具体的な使い方を見て行こう。
(2005_01_19)

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

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

 こんにちは、高橋真人です。
 さて、前回の最後で範囲演算子を使ってプログラムのパーツ作りをしているということをお話ししましたが、さすがにあの程度の単純な例だけではあまり活用の範囲は広くないと思いますので、活用範囲を広げるためのヒントをいくつかお伝えします。
 私がこのようなパーツ作りにPerlを利用するケースの多くはテーブル処理のためということがほとんどです。極めて単純な

char table[] = “ABCDEFGHIJKLMNOPQRSTUVWXYZ”;

なんていうものを作る場合だったら、手で打ってしまえばいいのですが、ASCIIの可視文字をコード順に並べたテーブルだとか、アルファベットの大文字小文字と数字という、ANSI Cのisalnum()に渡すと真になる値を羅列したテーブルなんてのも、コードで生成すれば手で打つよりも正確だったりするわけです。
 まずASCIIの可視文字をコード順に、という件ですが、そもそも可視文字の先頭がスペースで最後が~(チルダ)だということが分かっているならば、

print ‘ ‘..’~';

とやればいいように思われます。しかし、残念ながらこのコードは機能しません。理由に関しては正確なところは分からないのですが、PerlではCとは違って文字定数という概念はなく、従って文字列を数字として解釈はしないようです。
 それに、ASCIIの可視文字範囲の頭と終わりのコードを覚えていなかった場合、いちいちどこかからASCII表を引っ張りだして調べていたりしたら、何のためにラクをしようとしているのか分からないので、もっとお手軽な方法で切り抜けます。
 まず、以下のようなコードを書きます。

for (0..127) {
     print chr;
}


 これによって、ASCIIコードの$00から$7Fまでの文字が連続して表示されます。もちろん中には不可視文字も含まれていますから、表示は一部乱れます。
 コードの解説は後に回して、次に出力された結果を見て、最初の文字を見つけます。!が先頭のように見えますが、その一つ前が半角スペースになります。末尾の方はすぐに分かりますね。
 この結果を受けて最後に以下のようなコードを書きます。

for (ord ' ' .. ord '~') {
     print chr;
}


 これで完了です。ASCIIの可視文字がコード順に得られました。
 ではこのコードを解説しましょう。
 forというのはCでもおなじみのループのための制御構造ですが、Perlでは、Cにおけるforと同じ使い方のほかにforeachと等価にも使うことが可能です。
foreachというのは、

foreach $item (@list) {
     ...
}

といった形で使われる構文で、@listの中の要素を順に$itemの中に入れて、要素の数だけループをするというものです。AppleScriptをご存知の方でしたら、

repeat with theItem in theList

という構文と同じだと考えていただければよいでしょう。
 ただ、Perlの場合、foreachの直後の$itemの部分が省略された場合、配列の要素は$_という変数に入れられることになります。$_というのはPerlでは極めて頻繁に使われる特殊な変数で、演算子の多くでは引数を省略した場合に暗黙に$_という変数が与えられていると解釈します。よって、ループ内のprint chr;というコードでは、chrという「引数のコードに対応する文字を返す」演算子に対して、暗黙に$_が与えられているということになります。
 結果、先のループにおいては(0..127)というリストの要素が順番に$_という変数を通してprint chr;に渡されているのです。
 後半のループで使用したordというのは、引数として与えられた文字列の先頭の文字(バイト)のコード値を返す演算子です。

 次に、2番目に挙げた「アルファベットの大文字、小文字そして数字」という文字列の作成ですが、これは考えてみたらfor構文は必要なかったですね。

print ‘A’..’Z', ‘a’..’z', ’0′..’9′;

 これだけでOKです。範囲演算子を使った範囲リストをさらにカンマでつなぐところがポイントです。リストはスカラー変数をカッコでつないだものですから、リストとリストをカンマでつないだものも、またリストとなります。

 さて、次回は今回のfor構文をさらに発展させていく方法についてお話しすることにします。

ニュース・解説

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

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

【開発環境】

サンフランシスコ Expoで行われた基調講演では、噂通りの新製品が大量に発表されました(リアルタイムのストリーミング放送がなかったのは残念でしたが…)。しかし、私が一番期待していた新型のPowerBook G4だけは、とうとう最後まで発表されませんでした(涙)。近々登場する予定はあるのでしょうか? 一番注目されていたモニターが外付け可能なマシン(Mac mini)もちゃんと発表されました。「WindowsユーザにMacintoshを購入してもらう」と言う戦略を担う大事なニューフェースですが、こうした製品が出せるようになったのも、Apple社にiPodという「もう一本の柱」が出来たからでしょう。

以前のApple社であれば、商品構成をやたらに増やす余裕がありませんでしたから、こうした企画自体がボツになっていたと想像されます。ところで、サブノート大好きの日本のユーザからは、「Mac miniが出せたのだから、PowerBook miniも出して欲しい!」という声が聞こえてきそうです。昔なら「日本だけでしか売れないマシンは×」(過去の苦い経験から…)の一声で企画はボツでしょうが、iPodで潤っている今であれば何とかなるかもしれません。ほんのちょっとだけ期待したいと思います(笑)。

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

前回から1月21日の期間中、Apple社のDocumentationサイトには新規ドキュメントが9つ登録されました。このうち、「Writing Drivers for Mass Storage Devices」「Transitioning to Quartz 2D」「Multithreading Programming Topics」の3つのドキュメントには大幅な改訂がなされていますが、それ以外はマイナーな改訂です。また、デベロッパ向けに「Automator」と「X11」を解説した2つの読み物が登録されています。

「Accessing Hardware From Applications」(PDFあり)
「Enterprise Objects」(PDFあり)
「Moving Projects From CodeWarrior to Xcod」(PDFあり)
「Multithreading Programming Topics」(PDFあり)
「Run Loops」
「Supporting Unicode Input」(PDFあり)
「Text Input Management」(PDFあり)
「Transitioning to Quartz 2D」(PDFあり)
「Writing Drivers for Mass Storage Devices」(PDFあり)

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

「Configuring and Running X11 Applications on Mac OS X」(読み物)

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

「Tiger Developer Overview Series: Working with Automator」(読み物)

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

前回から1月21日の期間中、新規のテクニカルノートはひとつも登録されませんでしたが、新規テクニカルQ&Aの方は4つ登録されました。QA1405とQA1398については、前号の新居さんの解説も参考にしてください。

QA1396「Creating color spaces that ensure color matching」
QA1405「Variable arguments in Objective-C methods」
QA1398「Mach Absolute Time Units」
QA1403「Sequence Grabber-Determining the capture resolution of an IIDC device」

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

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

前回から1月21日の期間中、Apple社のSample Codeサイトには、新しいサンプルソースコードがひとつだけ登録されました。「HIObjectThreadController」は、開始したスレッドの状況を表示するためのユーザインターフェースをHIObjectとして実装するサンプルアプリケーションです。以前に登録されていた物のマイナーな改訂版となっています。

「HIObjectThreadController 」(HIObject関連)

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

【デベロップメント SDK】

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

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

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

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