MOSA Multi-OS Software Artists

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

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

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

2005-09-27

目次

  • 「WebObjects Dev Report」     第23回  田畑 英和
  • 藤本裕之のプログラミング夜話 #77
  • 高橋真人の「プログラミング指南」  第75回
  • ニュース・解説                小池 邦人

「WebObjects Dev Report」  第23回  田畑 英和

 前回は「単一テーブル」型の継承を用いて親クラスとサブクラス用のEntityをモデル上に作成する方法を解説しましたが、今回は継承を用いた場合のカスタムEOのソースコード作成方法について解説いたします。

 「単一テーブル」を用いた場合、継承関係にあるすべてのEntityのデータが1つのテーブルに格納されます。そこで、複数のEntityが混在するテーブルの中から各レコードのEntityを識別するための、”type”という名前の属性を追加しました。カスタムEOのソースコードでは、この”type”属性に適切な値を入力する処理が必要になってきます。

◇ソースコードの作成
 まずは、EOModelerを用いて親クラスとサブクラス用の全てのEntityから、ソースコードを自動生成します。このとき、モデル上で継承関係にあるEntityは、自動的に適切な継承がおこなわれたクラスとしてソースコードの生成がおこなわれます。つまり、サブクラス用EntityであるMOSAMember,MOSANonMember, MOSAAdminは、それぞれMOSAUserから継承されたクラスのソースコードが生成されます。親クラス用EntityのMOSAUserは、通常どおりEOGenericRecordクラスから継承したクラスが生成されます。

・各クラスの継承関係
EOGenericRecord <- MOSAUser
MOSAUser <- MOSAMember
MOSAUser <- MOSANonMember
MOSAUser <- MOSAAdmin

 これで継承関係をもったクラスのソースコードが準備できましたので、次はそれぞれのクラスで、"type"属性に適切な値を入力する処理が必要になってきます。
 どのタイミングで"type"属性に値を入力するかですが、これはEOを新しく生成するときにおこないます。つまりEOの新規作成時に"type"属性を初期化してあげるわけです。こういった新規作成時の初期化処理をおこなうためのメソッドとしてawakeFromInsertion()が用意されています。

public void awakeFromInsertion(EOEditingContext ec)

 このawakeFromInsertion()をオーバーライドし、クラスごとに"type"属性に適切な値を入力してあげればよいわけですが、すべてのクラスでこのメソッドをオーバーライドする必要はなく、親クラス(MOSAUser)で一括して処理をおこなうことができます。例えば次のようなコードを記述します。

public void awakeFromInsertion (EOEditingContext editingContext) {
     super.awakeFromInsertion(context);
     setType(_userType());
}

 まずはsuperで親クラスのawakeFromInsertion()を呼び出し、次に"type"属性のセッターsetType()で値を入力します。次に_userType()を実装するわけですが、このメソッドで各クラスごとのユニークな値を取得するようにします。このメソッドはクラスごとに異なった値を返す必要がありますので、すべてのサブクラス上での実装が必要になってきます。例えばMOSAMemberの場合には次のようなコードになります。

public Integer _userType() {
     return new Integer(10);
}

 このときMOSAMemberで使用している"10"という値は、MOSAMemberであることを識別するための値ですので、あとは他のサブクラスでも同様なメソッドを値を変えて実装すれば、各クラスごとにユニークな値をEOの新規作成時に設定できるようになります。
 各クラスを識別する値ですが、次のように親クラスのMOSAUserで定数として宣言しておけば、値を一カ所にまとめておくことができます。

public static final Integer TYPE_MOSAMember = new Integer(10);
public static final Integer TYPE_MOSANonMember = new Integer(20);
public static final Integer TYPE_MOSAAdmin = new Integer(30);

 このとき各サブクラスの_userType()は次のようになります。

・MOSAMember
public Integer _userType() { return TYPE_MOSAMember; }
・MOSANonMember
public Integer _userType() { return TYPE_MOSANonMember; }
・MOSAAdmin
public Integer _userType() { return TYPE_MOSAAdmin; }

 これで、各サブクラスのインスタンス(EO)を生成(new)したとき、自動的に"type"属性には各サブクラスごとにユニークな値が入力されます。
 このとき入力した値は、前回解説した各サブクラス用Entityにモデル上で設定したQualifierの値と一致しています。つまり、"type"の値が"10"のレコードを全件取得すればMOSAMemberの全件が取得できることになります。

 今回は"type"属性に入力する値をIntegerの定数としてソースコード上で宣言していますが、ようするにクラスごとにユニークな値が入力できればよいので、例えば文字列を用いてもよいですし、値の入力方法は色々と工夫ができるところでもあります。

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

 やれやれようやく新シリーズである。……新シリーズというのも変か。でもなんかわくわくする言葉なんだよね。ブラディ・ファイト・シリーズとかMSGシリーズとか……。これらはみな、かつての新日本プロレスのシリーズ名。開幕戦はたいてい後楽園ホールで、あそこは狭いからたいがい満員になるんだけど、たまに玄関脇でダフ屋の親父が「今回は外人がしょぼいからなー」とかボヤイてたりとか……。まごうことなき昭和の風景だったなぁ、あれも。
 と、妙な方向に連想を突っ走らせて感慨にふけっている場合ではなかった。NSWindowの話だ。まずはふだんあんまり使うことのないこのクラスの初期化メッセージ、すなわちこれ……

-(id) initWithContentRect:(NSRect)contentRect
              styleMask:(unsigned int)aStyle
                backing:(NSBackingStoreType)bufferingType
                  defer:(BOOL)flag;

の話からはじめよう(他に、これの最後に「screen」が追加されたものと、Carbon の WindowRef から NSWindow を生成するのがあるんだけど、ここでの説明の骨子には関係ないので割愛する)。
 なぜこいつは「ふだんあんまり使うことがない」のだろうか。それは、通常、アプリケーションで使われるNSWindowのインスタンスはInterfaceBuilderを使って定義され、起動時にNibファイルから読み込まれて生成されてしまうからである。逆に言えば、その方法ではちと困る事情のあるインスタンスだけ、われわれがわざわざこいつを使って作らなければならない、のである。
 ……それはどんなモノか、と考える前に、ちょっとこれらのメッセージのパラメータを詳しくみておこうか。最初の contentRect は簡単だよね(パラメータとして)。これから作る ウィンドウ の「中身の部分」を指定する矩形である。次の aStyle というのは文字通りウィンドウのスタイルを指定するスイッチで、StyleMaskとある通りビット列で指定する。各ビットは「NSWindow.h」に以下のように定義されている。

enum {
    NSBorderlessWindowMask = 0,
    NSTitledWindowMask = 1 << 0,
    NSClosableWindowMask = 1 << 1,
    NSMiniaturizableWindowMask = 1 << 2,
    NSResizableWindowMask = 1 << 3
};

 次の bufferingType は、指定できる値が NSGraphics.h の中に次のように定義されていて、これはつまりウィンドウの描画のしかたである。普通はNSBackingStoreBuffered を指定しておくもんだと思うが、頻繁に高速な描き替えが必要な場合はバッファリングをしない(NSBackingStoreNonretained)とか、隠されてる部分にだけバッファを使う(NSBackingStoreRetained)を指定する……んだと思う。実際のところ、あんまりその効果を実感できたことはないんだよね。やってる処理によるのかな。……もしかして、オレだけ?

typedef enum _NSBackingStoreType {
    NSBackingStoreRetained     = 0,
    NSBackingStoreNonretained  = 1,
    NSBackingStoreBuffered     = 2
} NSBackingStoreType;


 最後の flag には、簡単に言うとウィンドウの描画に関わる命令の実行を、実際にウィンドウがスクリーンに持って来られるまで(まぁ「開くまで」と言ってもいいが)延期するというか、サボるかどうかを指定する。これが YESだと、ウィンドウの描画に関わる命令はすべて保留され、「さぁそのウィンドウを前面に持って来い」と言われた時に一気に実行される。そんなソバ屋の出前みたいなことになんの効用があるかというと……あ、ちと長くなってしまったな。次回はその効用から。
(2005_09_21)

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

UNIXとしてのMac OS X

〜Perlについて(21)〜

 こんにちは、高橋真人です。
 前回紹介した「言明」(Assertion)は、少し分かりにくかったかもしれません。実際、私が日常的に正規表現を使う中でも、^ や $ は頻繁に使いますが、?b に関しては、ほとんど出番がないというのが実際のところです。
 その代わりというわけでもないのですが、言明に似たようなものとして今回は ? にアルファベットを組み合わせることで表現できるもの(これらを総称して「メタ文字」と表現している文献もあります)をいくつか紹介します。
 これらは以前紹介した文字クラスの代用として用いることができます。代表的なものを紹介します。参考までに、文字クラスで書いた場合にどうなるかを併せて記しておきます。

¥d ... 数字を表す [0-9]と同じ
¥D ... 数字以外を表す [^0-9]と同じ
¥w ... 単語を構成する文字を表す [a-zA-Z0-9_]と同じ
¥W ... 単語を構成する文字以外を表す [^a-zA-Z0-9_]と同じ
¥s ... 空白文字を表す [ ¥t¥r¥n¥f]と同じ
¥S ... 空白文字以外を表す [^ ¥t¥r¥n¥f]と同じ

 ¥sのところで出てくる¥fは、フォームフィードすなわち改ページ文字です。
 前回登場した?bにせよ、今回の¥wや¥sにせよ、あくまで単語が空白によって区切られる「分かち書き」の表記が前提となっていることは明白で、その意味で日本語を正規表現で処理するには多少の追加措置が必要になってくることは、まあプログラマの皆さんならばご承知の通りです(笑)

 さて、今回紹介した表記法を使うとどういうことができるのかという例を2つ紹介します。
 まず、前回も登場した、以下のようなテキスト。

orange, banana, peach, apple and cherry

 ここから単語を拾い出すような場合には、/¥w+/という表現で一発です。ただし、'and'も単語として拾い出しますので、さすがに「名詞だけ」というよいな抽出の仕方は無理ですがね。これだけではナンなので、きちんと走るPerlスクリプトにしておきます。

$_ = 'orange, banana, peach, apple and cherry';

while (/¥w+/g) {
    print $&, "¥n";
}


 これで各単語を順番に行として出力するようになります。以前触れたm//演算子のgオプションが使われていることに注意してください。これが指定されないと、このループは永久ループになってしまいます。(何度繰り返しても'orange'にしかマッチしない)

 もう一つの例は、やはり前回触れた「各行の末尾の空白(不可視文字)を消し去る」方法です。前回は半角スペースとタブのみを対象としましたが、今回は、/¥s+$/という表現で処理してみます。
 スクリプトとして仕立ててもよいのですが、このケースはエディタなどで使う方が重宝するはずなので、正規表現対応のエディタで試してみました。(miとJedit Xで検証)
 前回の、半角空白とタブのみの指定に対して、今回のように¥sを使った場合には、他の「空白文字」も対象となります。ちょっと興味深いのは、$という末尾指定の言明指示子と改行文字との絡みがどのようになるのかということです。(通常、$は改行文字を表すものとして考えるケースが多いのです)
 早速実験してみたところ、末尾の空白文字のみならず、いわゆる空白行(改行のみの行)や、加えて空白文字を一つ以上含んだ行もきれいに取り去ることができました。
 ちなみに、全角空白が含まれた行に関してはこの限りでないことは言うまでもありません(泣)

ニュース・解説

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

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

【開発環境】

Mac OS X 10.4になり、Carbon関連のヘッダーファイルに定義されているAPIのコメントに「*** DEPRECATED *** 」という表記が追加されている場合があります。DEPRECATEDを訳すと、非難する、反対を唱える、軽視するとかになるのですが、どうも「廃止予定」と言う意味のようです。この「DEPRECATED」で、色々なヘッダーファイルを検索してみると、QuickDraw.hだけではなく、Files.hとかPMApplication.hなどでも数多くのAPIが廃止予定であることが分かります。

Xcode 2.1のインストール時に、Developer/SDKsフォルダ内にMacOSX10.4u.sdkもインストールし、それを利用可に設定しておくと、Make時にDEPRECATEDが付いたAPIの使用にはWarningが表示されます。なんだかとても気分が悪いのですが(笑)、筆者が以前作成した湘南ミーティング用の簡単なサンプルでも、160以上のWarningが表示されてしまいました(涙)。しかし、GetWindowBounds()はOKなのに、SetRect()やOffsetRect()はダメなのは納得できませんねぇ。もう少し廃止対象APIの選定をちゃんとした方が良いような気がします...。

ところで、「廃止予定」は理解できるのですが、Apple社はいったい「いつ」廃止するのでしょうか?時期Mac OS X 10.5(Leopard)投入時でしょうか?今すぐ、これらのAPIを廃止したら、起動しなくなるソフトが大量に出現してしまいます。また、ヘッダーファイルから消してしまうと(APIは残すとして)、古いソフトは再リンクできなくなり、メンテナンスは不可能となります。多分、最終的には、SDKを10.4用と10.5用に切り替え可能にするのでしょうね(10.4用にはDEPRECATED APIを残す)。兎にも角にも、サヨナラするのはQuickDrawだけではなさそうです。

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

前回から9月23日の期間中、Apple社のDocumentationサイトには新規ドキュメントがひとつも登録されませんでしたが、新規リリースノートの方は4つ登録されました。また、デベロッパー向け読み物もひとつ登録されています。Javaに関連するリリースノートについては、前号の木下さんの記事も参照してみてください。

リリースノート

「Java 1.3.1 and 1.4.2 Release 2 Release Notes」(PDFあり)
「J2SE 5.0 Release 1 for Mac OS X Release Notes」(PDFあり)
「Java 1.4.2 for Mac OS X v10.4 Release Notes」(PDFあり)
「WebObjects 5.3 Release Notes」(PDFあり)

http://developer.apple.com/releasenotes/

「SolidWorks Brings eDrawings to Mac OS X」(読み物)

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

前回から9月23日の期間中、新規テクニカルノートは2つ登録されました。また、新規テクニカルQ&Aの方は3つ登録されています。TN2026では、MLTE(Multilingual Text Engine )の処理に関する「よくある質問と回答」がまとめられています。いつもいつも、MLTEの処理で苦労させられているCarbonデベロッパーの方は必読でしょう(笑)。テクニカルQ&Aについては、前号の木下さんの記事も参照してみてください。

TN2139「Debugging Dashboard Widgets」
TN2026「Multilingual Text Engine Frequently Asked Questions」

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

QA1412「How can I add the ability to read and write Keynote 2 documents to my application?」
QA1441「UpdateMovieResource causes my movie file to grow bigger」
QA1443「Using QTPixelBufferContext- Create with NewMovieFromProperties」

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

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

前回から9月23日の期間中、Apple社のSample Codeサイトには、新しいサンプルソースコードがひとつだけ登録されました。テクニカルQ&Aの「Using QTPixelBufferContext- Create with NewMovieFromProperties」と連動したサンプルとなっています。

「QTPixelBufferVCToCGImage」(QuickTime関連)

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

【デベロップメント SDK】

前回から9月23日の期間中、Apple社のSDKサイトには新しいSDKがひとつだけ登録されました。Windows用のQuickTime 7.02 SDKです。 実際に確認はしていませんが、聞いたところでは、Core VideoやCore FoundationなどMac独自のAPIが使えるそうです。

「QuickTime Windows SDK」

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

また、以下のサイトからCHUDの最新版である4.2.2がダウンロード可能です。これをインストールすると、「システム環境設定」のハードウェアのカラムに「Processor」環境設定がインストールされます。以前、この環境設定のリソースには「x4」マークの画像ファイルが存在しており、色々と憶測を呼びましたが、今回はどうも「x6」マーク(?)の画像までもあるようです(笑)。さて、どうなることやら?

「Computer Hardware Understanding Development Tools (CHUD )4.2.2」

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

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

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