MOSA Multi-OS Software Artists

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

プログラマーに興味がある方なら誰でも入会いただけます。
MOSA Multi-OS Software Artists
===SINCE 1995===

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

MOSADenバックナンバー 2005年4月発行分

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

    2005-04-26

    目次

    • 「WebObjects Dev Report」    第4回   田畑 英和
    • 小池邦人の「Carbon API 徒然草」
    • SqueakではじめるSmalltalk入門  第38回  鷲見 正人
    • ニュース・解説               木下 誠

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

    10.3.9問題

     Tigerがもうまもまくリリースされますが、そんなところに10.3.9へのアップデートがリリースされました。これがPanther(10.3)の最終形かと思われますが、さっそく10.3.9をインストールしたところとんでもないことになってしまいました。今回は、まずは10.3.9に関する問題とその解決方法からレポートします。

     10.3.9をインストールするとまず影響を受けるのがJavaプログラムです。つまりWebObjectsアプリケーションも影響を受けることになります。これは独自に開発したプログラムだけではなく、JavaMonitorなど標準で提供されているJavaアプリケーションにも影響を与えます。
     具体的な症状としては、Javaプログラムが起動しなくなります。ターミナル上でJavaプログラムを起動しようとすると最後に「Segmentation fault」と表示され、プログラムの起動に失敗します。
     この問題に関してはすでにAppleから解決方法が公開されており、まず問題の確認方法として以下のコマンドの利用が紹介されています。またJavaプログラム以外にもSafariでも問題が発生することが報告されています。

    ・10.3.9 Updateにともなう問題点の確認方法
    % java -version

     これはもともとJavaのバージョンを調べるためのコマンド(オプション)ですが10.3.9の問題にひっかかっている場合、コマンドの実行時にさきほど紹介した「Segmentation fault」が表示されます。これが表示された場合問題があるということです。
     では肝心の解決方法はといいますと、「Java 1.4.2 Update 2」と「Security Update 2005-002」をインストール(場合に寄っては後者だけ)する方法が紹介されています。問題が発生したマシンにこのアップデートを適用したところ無事Javaプログラムが起動するようになりました。
     今後この問題点を修正したアップデートがリリースされるかどうかは分かりませんが、これから10.3.9へのアップデートをおこなう方はくれぐれもご注意ください。*1

    ・10.3.9 Updateにともなう問題の解決方法
    http://docs.info.apple.com/article.html?artnum=301380

    *1
    原稿執筆後、Java Update for Mac OS X 10.3.9がリリースされました。今回の問題を解消するアップデートでソフトウェアアップデート経由で配布されています。
    http://www.apple.com/support/downloads/javaupdateformacosx1039.html

    Eclipse

     さて、ここからようやく本題ですが、先週は開発環境の準備について解説しました。今回はその続きとしてEclipseでWebObjectsの開発環境を整える方法を紹介しておきます。

     まずEclipseですが、これは様々なツールを組み合わせた開発環境であり、”universal tool platform”といった呼ばれ方もされています。特にJavaの開発ではすっかり市民権を得ており、解説書も多数出版されています。
     Eclipseは、いわゆるオープンソースとして公開されていて、Mac OS X版も利用することができます。マシンリソースがそれなりに要求され、以前は動作が遅くてなかなか満足に利用できなかったりもしましたが、最近の環境ですとようやく普通に使えるようになってきました。

     このEclipseはプラグインを追加することにより、機能を拡張できることが特徴ですが、WebObjectsのためのプラグインが開発されており、こちらを利用することでEclipse上でWebObjectsの開発をおこなうことができます。

    インストール

     ではまずインストールです。EclipseのサイトからMac OS X用のEclipseをダウンロードしてください。ちなみにこの原稿を執筆している時点での最新版は3.0.2となっています。

    ・Eclipseダウンロード
    http://www.eclipse.org/downloads/index.php

     ”eclipse-SDK-3.0.2-macosx-carbon.tar.gz”というファイルがダウンロードできますが、インストール方法はいたって簡単です。ファイルを解凍するだけですぐにEclipseが利用できるようになります。解凍すると”eclipse”フォルダが作成されますが、この中に”Eclipse”(ターミナル上ではEclipse.app)というファイルがありますので、これをダブルクリックするとEclipseを起動できます。あとは必要に応じて”eclipse”フォルダを移動してください。

    WOLips

     Eclipseの準備が整った次はWebObjects用のプラグインのインストールですが、WebObjects向けのプラグインはORマッパー「Cayenne」の開発でも有名なObjectStyleのWebサイトで公開されています。プラグインは「WOLips」と呼ばれており、最新版はVer 1.1.0.102 RC 2がリリースされています。

    ・WOLips
    http://www.objectstyle.org/woproject/index.html

     WOLipsをEclipseに組み込む方法ですが、ダウンロードしたWOLipsをあらかじめ解凍し、Eclipseを起動します。Eclipseを起動しますとワークスペースの選択が求められますが、このワークスペースとは作成したプロジェクトの保存先になります。自分のホーム内にワークスペースを作成することもできます。
     ワークスペースを選択してEclipseが起動したら、次に「Help」メニューから「Software Updates」->「Find and Install…」を実行し以下の手順でインストールをおこなってください。

    1.「Install/Update」画面で「Search for new features to ins…」を選択
    2.「Next」ボタンをクリック
    3.「Install」画面で「New Local Site…」ボタンをクリック
    4. あらかじめ解凍しておいたWOLipsのフォルダを選択
    5. リストに選択したWOLipsが追加されたらチェックボックスをチェックし、「Next」ボタンをクリック
    6. 4つの項目が表示され、すべてをチェックし「Next」ボタンをクリック
    7. ライセンスが表示されるので、じっくり確認
    8.「I accept the terms in the license agreeme…」を選択し、「Next」ボタンをクリック
    9. 「Finish」ボタンをクリック
    10. 計4回の確認画面が表示され、それぞれ「Install」ボタンをクリック
    11. 最後にEclipseを再起動

     以上の手順でEclipseにWOLispが組み込まれます。これでいよいよEclipse上でWebObjectsの開発環境が整ったことになりますが、次回はEclipse + WOLipsでの開発方法について解説し、そろそろビジネスマッチングシステムの話を進めていきたいと思います。

    小池邦人の「Carbon API 徒然草」(2005/04/22)

    ドラッグ&ドロップの活用(その2)

    今回は、Finderでドラッグされたアイコンがターゲット領域(ブラウザコントロール)へドロップされた瞬間の処理について解説します。具体的には、InstallReceiveHandler()で登録されているmyReciveDrag()ルーチンから順次処理を追跡していきます。

    以下が、InstallReceiveHandler()で先んじてインストールしておいたmyReciveDrag()ルーチンです。

    pascal short myReciveDrag( WindowPtr window,long *refcon,DragReference dref )
    {
        short            ret=1;
        CGrafPtr         cptr;
        Point            pt;
        unsigned short   ct;
    
        GetPort( &cptr );              // カレントポートを保存する
        SetPortWindowPort( window );   // カレントポートをカタログウィンドウにする
        HideDragHilite( dref );        // ターゲット領域の強調色を元に戻す
        GetDragMouse( dref,&pt,NULL ); // ドロップされた座標を得る
        GlobalToLocal( &pt );          // ドロップ座標をローカル座標へ変換
        CountDragItems( dref,&ct );    // ドラッグされたアイテムの個数を得る
        switch( GetWRefCon( window ) ) // ウィンドウの種類をチェックする
        {
            case 'CATA':     // ドロップされたのがカタログウィンドウ内の場合
    
                ret=reciveCatalogWindow( window,dref,ct,pt ); // 実際のReceive処理へ
                break;
        }
        SetPort( cptr );              // カレントポートを復帰する
        return( ret );
    }
    


    myReciveDrag()には3つの引き数が渡されます。最初にSetPortWindowPort()でターゲットとなるウィンドウをカレントポートに設定し、HideDragHilite()でターゲット枠の強調表示を消します。アイコンのドロップ位置のグローバル座標はGetDragMouse()で得ることができるので、GlobalToLocal()でカタログウィンドウのローカル座標へと変換しておきます。また、CountDragItems()によりドロップされたオブジェクト数を得ることができます。こうした情報をまとめて次のreciveCatalogWindow()ルーチンに渡すことで、実際のRecive処理を実行します。

    本サンプルアプリケーションでは、アイコンに添付されてくる’hfs ‘というタイプのデータのみを受け取ります。このデータの実態は、HFSFlavorという構造体であり、その内容はGetFlavorData()で得ることが可能です。この構造体には、ドロップされたファイルやフォルダのFSSpec構造体やファイルタイプが含まれています。reciveCatalogWindow()では、ファイルタイプにより次の3つの処理を実行します(ソースコードに番号を添付)。

    (1)アイコンがフォルダやボリュームの場合
    (2)アイコンがドキュメントファイルの場合
    (3)アイコンが表示可能な画像ファイルの場合

    #define BROW_ID    100        // ブラウザコントロールのID番号
    #define MY_DOC    'MosD' // サンプルアプリ・ドキュメントのファイルタイプ
    
    short reciveCatalogWindow( WindowPtr window,DragReference dref,
                                                      unsigned short ct,Point pt )
    {
        Boolean          folder,alias;
        FSSpec           fsc,fsc1;
        short            i,ret=1;
        ControlRef       browser;
        FInfo            info;
        FlavorFlags      flag;
        ItemReference    item;
        OSType           type;
        HFSFlavor        hfs;
        Rect             brt;
        long             len;
    
        getMyControlRef( window,BROW_ID,&browser ); // ブラウザのControlRefを得る
        GetControlBounds( browser,&brt );           // ブラウザの矩形枠を得る
        for( i=1;i<=ct;i++ ) // ドロップアイテムの個数分ループさせる
        {
            GetDragItemReferenceNumber( dref,i,&item ); // 指定番号のアイテムを得る
            if( ! GetFlavorFlags( dref,item,'hfs ',&flag ) ) // 'hfs 'タイプか?
            {
                GetFlavorDataSize( dref,item,'hfs ',&len ); // データ容量を得る
                GetFlavorData( dref,item,'hfs ',(Ptr)&hfs,&len,0L ); // データを得る
                if( PtInRect( pt,&brt ) )  // ブラウザ内へのドロップか?
                {
                    fsc=hfs.fileSpec;  // アイコン(ファイル)のFSSpecを得る
                    type=hfs.fileType; //  アイコンのファイルタイプを得る
    
                    ResolveAliasFile( &fsc,1,&folder,&alias ); // エイリアスか?
                    if( alias ) // アイコンはエリアスである
                    {
                        if( folder ) // フォルダやボリュームのエイリアスか?(1)
                        {
                            getFolderFSSpec( &fsc,&fsc1 ); // フォルダのFSSpecを得る
                            ret=addImageFolder( window,&fsc1 ); // フォルダ内を登録
                        break;
                        }
                        else
                        {
                            FSpGetFInfo( &fsc,&info ); // ファイル情報を得る
                            type=info.fdType;          // ファイルタイプを再設定する
                        }
                    }
                    if( ( type=='fold' || type=='fldr' || type=='disk' ||
                                       type=='srvr' ) && hfs.fileCreator=='MACS' )
                                       //  アイコンはフォルダやボリュームか?(1)
                    {
                        getFolderFSSpec( &fsc,&fsc1 );     // フォルダのFSSecを得る
                        ret=addImageFolder( window,&fsc1 ); // フォルダ内を登録する
                        break;
                    }
                    if( type==MY_DOC ) // ドキュメントかどうか?(2)
                    {
                        if( ! loadObjectFile( window,&fsc ) ) // ドキュメントロード
                        {
                            mainteAddImageFile( window ); // ウィンドウをメンテする
                            ret=0;
                        }
                    }
                    else
                    {
                        navCheckImportExtention( fsc.name,&type ); // 拡張子チェック
                        if( ! navImportCheckTypeList( type ) ) // 登録可能か?(3)
                        {
                            if( ! addImageFile( window,1,&type,&fsc ) ) //登録する
                                ret=0;
                        }
                    }
                }
            }
        }
        return( ret );
    }
    


    ファイルタイプの違いで処理を分岐する前に、得られたFSSpecをResolveAliasFile()に渡してドロップされたアイコンがエイリアスかどうかを調べます。もしエイリアスであれば(aliasがTRUE)、渡したFSSpecがオリジナルの物と差し替えられて戻ります。アイコンのオリジナルがフォルダであれば(folderがTRUE)、getFolderFSSpec()でフォルダ自身のFSSpecを求め、それをaddImageFolder()ルーチンに渡して内部にある画像ファイルをすべてブラウザに登録します。また、オリジナルがファイルであれば、FSpGetFInfo()でそのファイル情報を得て、正しいファイルタイプを設定し直しています。

    ファイルタイプが'fold'や'fldr'であればフォルダアイコンが、'disk'や'srvr'であればボリュームアイコンがドロップされたことを示します。この場合の処理は、エイリアスがフォルダだった場合とまったく同じです。ファイルタイプが'MosD'であれば、これはサンプルアプリケーションのドキュメントですので、loadObjectFile()ルーチンでファイル読み込み処理を実行します。それ以外のファイルタイプであれば、画像ファイルである可能性が残されています。まず、navCheckImportExtention()ルーチンで拡張子を調べてから、navImportCheckTypeList()で登録可能(QuickTimeで表示できる)画像ファイルかどうかを見極め、addImageFile()ルーチンに渡してブラウザへと登録します。

    本サンプルアプリケーションは、ウィンドウ全領域をドロップターゲットとはせず、ウィンドウに配置したID=100のブラウザコントロールの矩形枠内のみをターゲットとしています。ちなみに、上記ルーチンでは、PtInRect()を用いて矩形内かどうかを判断をしていますが、もしTrack処理側でも同じ処理を行っていれば、ここで再度行う必要はありません(Recive処理だけインストールした場合には必要です)。今回の例でも分かりますが、外からのデータを受け取る処理(Receive処理)のみを実装するだけなら、Drag Managerは割と簡単に利用できます。

    次回は、Receive処理の話の続きです。reciveCatalogWindow()の中から呼ばれている自作ルーチン、addImageFolder()やaddImageFile()などについて詳しく解説したいと思います。

    つづく

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

     本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。Smalltalkプログラミングには欠かせないコレクション。このコレクションの抽象クラス「Collection」のプロトコルである、accessing、adapting、adding、arithmetic、enumerating、converting、それぞれに属するメソッドを起動するためのメッセージが送信されたとき、コレクションがどんな振る舞いをするのかをこれまで見てきました。今回は残りのmath functions、removing、testingの各プロトコルを取りあげます。

     math functionsプロトコルには、単項メッセージで起動され、そのとき代数的関数のような役割りを果たすメソッドがまとめられています。

    #(1 2 3 4) sum " => 10 " "合計を求める"
    #(1 2 3 4) min " => 1 " "最小値 "
    #(1 2 3 4) max " => 4 " "最大値 "
    #(1 2 3 4) negated " => #(-1 -2 -3 -4) " "各要素の符号反転"

     Collectionのmath functionプロトコルを閲覧している状態で、ブラウザ上段右端のペインから各メソッド名(セレクタ)をクリックすると、対応するメソッドの定義が下のコードペインに表示されます。このプロトコルに属するメソッドは、#sumや#max、#minのように結果を求めるために特殊な手続きが必要なタイプのものと、#negatedのように#collect:を使って、各要素に単純にメッセージを送り直した結果を新しいコレクションとして返すタイプのものに大別できます。

    Collection >> max
       ^ self inject: self anyOne into: [:max :each | max max: each]
    
    Collection >> negated
       ^ self collect: [:a | a negated]

     ちなみにanyOneは、レシーバの適当な(実際には最初の)要素を返すメソッドを起動するメッセージです。

     arithmeticプロトコルに属するメソッド同様、math functionsに属するメソッドも、起動時のコンテキストにおいてレシーバのすべての要素が数値かそれに準ずるものであることが期待されます。

    #(1 #two 3 4) negated " => error "

     removingプロトコルには、レシーバから要素を取り除くためのメソッドが属します。基本的なメソッドは、#remove:、#remove:ifAbsent:、#removeAll:です。addingプロトコルのメソッド同様、removingプロトコルのメソッドも削除した要素を返値とする慣習があるので、ここでは便宜的にレシーバを返すyourselfというメッセージを送っています。

    #(1 2 2 3 3 3) asSet remove: 2; yourself   " => a Set(1 3) "
    #(1 2 2 3 3 3) asSet remove: 4  " => Error: Object is not in the collection. "
    #(1 2 2 3 3 3) asSet remove: 4 ifAbsent: []; yourself  " => a Set(1 2 3) "
    #(1 2 2 3 3 3) asSet removeAll: #(1 2); yourself  " => a Set(3) "

     メッセージ「remove: oldElement」は、レシーバからoldElementを削除します。もちろん、要素の増減が可能なコレクションに限ります。

    #(1 2 3) remove: 2
       " => Error: This message is not appropriate for this object "

     取り除こうとする要素がレシーバに含まれているかどうかわからないときは、メッセージ「remove: oldElement ifAbsent: [...]」を送ります。第二パラメータのブロックには、削除したい要素がレシーバに見つからないときの処理を記述します。何もしないときは上述のように空のブロック「[]」を渡しておけばよいでしょう。

     メッセージ「removeAll: aCollection」は、aCollectionに含まれる要素をすべてレシーバから削除します。これは、aCollectionに対する要素の列挙と、#remove:を使って表現できそうですね。実際に#removeAll:を見てみると、たしかにその通りの定義になっています。

    Collection >> removeAll: aCollection
       aCollection do: [:each | self remove: each].
       ^ aCollection

     コレクションのプロトコル探索の最後はtestingです。ここで注目するメソッドは、#includes:、#isEmpty、#occurrencesOf:です。

    #(1 2 2 3 3 3) includes: 2       " => true  "
    #(1 2 2 3 3 3) includes: 4       " => false "
    'squeak' includes: $a            " => true  "
    'squeak' includes: $x            " => false "
    #(1 2 2 3 3 3) isEmpty           " => false "
    #() isEmpty                      " => true  "
    'squeak' isEmpty                 " => false "
    '' isEmpty                       " => true  "
    #(1 2 2 3 3 3) occurrencesOf: 4  " => 0     "
    'SMALLTALK' occurrencesOf: $L    " => 3     "

     「includes: anObject」はレシーバがanObjectを含むかどうかを真偽値で返させます。isEmptyは、単純にレシーバが空(カラ)つまり要素を*持たない*か否かを、やはり真偽値で返させます。

     isEmptyの逆、つまり、要素を*有する*か否かを聞きたいときは、isEmptyの返値にnotを送信して反転させる…という手の他に、notEmptyというメッセージを送る方法もあります。

    #(1 2 2 3 3 3) isEmpty not   " => true "
    #(1 2 2 3 3 3) notEmpty      " => true "

     メッセージ「occurrencesOf: anObject」は、anObjectのレシーバ内での出現回数を尋ねるときに送ります。

     以上、駆け足でしたが、Smalltalkのコレクションが共通して受け付けるメッセージと、そのときに期待される振る舞いについての簡単な解説を終わります。

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

    ニュース・解説

     今週の解説担当:木下 誠

    ----------------------------------------------------------------------
    QuickTimeアプリケーションのモダン化
    ----------------------------------------------------------------------

    QuickTimeアプリケーションをモダン化するためのドキュメント「Modernizing QuickTime Applications Part I」が、公開されていました。これは、古いQuickTimeのAPIを使っているアプリケーションを、QuickTime 6系のAPIに移行させるための、ガイドとなるドキュメントです。

    このドキュメントに、特に新しい内容が含まれる訳ではなく、QuickTime 6 APIのサマリーとなっています。各機能の説明では、サンプルのコードを多く含み、かなり大きなドキュメントになっています。さらにタイトルに「Part I」と付いているので、おそらく後日Part IIも公開されるのでしょうから、膨大な量になりそうです。

    QuickTime 7の登場を間近に控えていますが、古いアプリケーションのメンテナンスをしたり、QuickTime APIの概要をつかむのに、便利なドキュメントでしょう。

    Technical Note TN2140: Modernizing QuickTime Applications Part I
    http://developer.apple.com/technotes/tn2005/tn2140.html

    ----------------------------------------------------------------------
    Mac OS X 10.3.9のJavaの問題
    ----------------------------------------------------------------------

    先日、Mac OS X 10.3.9が公開されましたが、アップグレードすると、JavaアプリケーションやSafariでJavaを利用するWebページを開いたときに、問題が発生しました。具体的には、アプリケーションがクラッシュしたり、起動しなくなりました。その問題を解決するJava Update for Mac OS X 10.3.9と、その解説を行なうドキュメントが公開されました。

    問題の原因は結局、javaコマンドでバージョンを表示させる、'java -version'でセグメンテーション・フォールトが発生していた、ということのようです。

    Java Update for Mac OS X 10.3.9
    http://www.apple.com/jp/ftp-info/reference/javaupdateformacosx1039.html
    About the Java Update for Mac OS X v10.3.9
    http://docs.info.apple.com/article.html?artnum=301382

    ----------------------------------------------------------------------
    WindowsからMacへ、Visual BasicからREALbasicを利用して
    ----------------------------------------------------------------------

    WindowsアプリケーションをMac環境に、数日で移植した例が紹介されていました。CompuTestという会社が、2004年の夏に行なった事例だそうです。

    彼らは、WindowsのVisual Basicで書いたソフトを販売していましたが、Mac版の開発の要求を受けて、REALbasicを使って移植することを試しました。その結果、12日で移植を完了することが出来たそうです。

    A Pleasant Surprise for CompuTest: Porting From Windows to Mac in Days Instead of Months
    http://developer.apple.com/business/macmarket/electronicbluebook.html

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

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

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

    2005-04-19

    目次

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

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

     さてさて、皆さんもうご存知かと思いますがいよいよTigerの発売日が発表になりました。4/29(金)に発売され、Mac OS X Server v10.4も同じ日に発売されます。TigerにおいてWebObjectsがどのような扱いになるのかはまだ詳細が公開されていないようですが、詳細が分かり次第またレポートしたいと思います。
     WebObjectsそのものがアップデートされていないからには、あまり期待もできませんが、Javaのバージョンも上がっていくことでしょうし、Xcodeも進化していますので、せめて最新の環境は確実にサポートしてもらいたいものです。

    開発環境の準備

     さて今回は開発環境の準備について解説していきたいと思います。あらためてWebObjectsの開発環境を確認してみますと、カタログスペック上では次のようになっています。

    ・開発プラットフォーム
      Mac OS X v10.2.2以降
      Windows 2000 Professional SP3

     「v10.2.2以降ってことは当然Tigerも動作環境に含まれるんだな」とおもわずツッコミを入れたくなりますが実際のところはどうなのでしょうか。Tigerの発売はもう少しだけ先のことですので、Mac OS Xの最新版はv10.3.8(編集部注釈:執筆時での最新版)ということになりますが、開発環境のXcodeは1.5(Tigerでは2.0)がリリースされています。
     ところがWebObjectsの最新版である5.2.3 Updateの説明をみてみますとシステム条件としては以下のとおりになっています。

    ・WebObjects: 5.2.3 Updateについて
    http://til.info.apple.co.jp/techinfo/107873
     Mac OS X 10.3.3以降
     Xcode 1.1 Developer Tools
     Java 1.4.2

     またインストールの手順をみてみますと、Mac OS X 10.3からインストールを始める手順が紹介されています。5.2.3がリリースされたのが約1年前のことですので環境としてはまあこんなものかなとも思いますが、ここで紹介されているアップデート方法はOSのアップデータが1回(10.3 -> 10.3.3)、Xcodeのアップデートが1回(Xcode -> Xcode 1.1)、WOのアップデートが3回(5.2->5.2.2 -> 5.2.3)とかなり手間のかかる手順になっています。
     さらに今となっては少し古い環境になっていますし、この手順どおりにインストールしようとすると、最近の機種ではすでにアップデート済みの10.3がバンドルされており、10.3のCDではそもそもブートができなくなっていますので、手順どおりにはインストールできないことになります。
     少し古い機種で、一通りインストールした環境のディスクイメージを作成しておいて、そちらを開発マシンにリストアするという方法がありますが、これだとさらに手間がかかってしまいます。

     なぜこんな細かいことを解説しているかといいますと、最近何度かWOの開発環境をセットアップする機会があったのですが、5.2.3のアップデートで説明されている手順でないとうまく開発環境を構築することができなかったからです。
     5.2.3までアップデートすることはできるのですが、いざプロジェクトを作成してみると、なにもコードを加えていない状態でも試しにビルドしてみるとビルドに失敗することがあります。「WebObjects Application」タイプのプロジェクトはビルドできても、「WebObjects Framework」タイプのプロジェクトはビルドできないといった症状が確認できています。
     おそらくビルド時に参照するなにかのファイルパスがうまく設定されていないのではないかと思いますが、素直に5.2.3のアップデートの手順どおりに環境を構築した場合には、もちろん問題なく開発環境を構築することができました。

     以前から開発をおこなっている経験豊富なデベロッパーならこんな状況でもなんとかなるかもしれませんが、残念ながらこれから初めて開発をおこなう場合は少し注意が必要です。もし開発環境を構築してみてなにか変なことがあればまずは手順どおりにアップデートをかけてみることをおすすめします。現状では、この5.2.3のアップデートで説明されている手順が確実にインストールをおこなえる手順になります。
     もともとアップデートの手順が複雑なうえに、最新の開発環境がまだサポートされていませんので、いいかげんなんとかしてもらいたいものです。

     さてなんだか今回はぐちっぽい記事になってしまいましたが、今回紹介した純正の開発環境の他に、Eclipseを用いてWebObjectsの開発をおこなう環境も整備されてきています。次回はEclipseを用いた開発環境についてご紹介したいと思います。

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

     さてお待ちかねのマチカネコイノボリ(という名前の馬がむかぁし関西にいたんだよ)、NSViewのお話である。まずは概略、ドキュメントを見ればこのクラスは、NSResponderのサブクラスである。え、それを言ったらNSApplicationもそうだったではないかって? そうなんだけどNSResponderのことをいろいろ説明するにはここで取り上げた方が都合がいいのでここまで温存したわけ。けして忘れていたわけではない、ありません(咳)。

     NSResponderというのはabstract class、日本語でいうと抽象クラス。……これ、日本語でいってもちっとも解りやすくならないことが多いコンピュータ用語の中でも東の大関級に解りやすくならない言葉だけれども、早い話が「それ単体ではインスタンスを生成できないクラス」である。JavaやC++にもあるでしょ、あれと同じ。

     ただひとつ、Objective-Cにおける抽象クラスには他の言語のそれと大きく違う点がある。それはObjective-Cにおける抽象クラスというのが、その存在自体抽象的なもんであるということ。……いや別にトートロジーで遊んでるわけぢゃなくてね、たとえば上で言ったようにNSResponderが抽象クラスだとすると、JavaやC++的常識に照らせば、あなたは(オレも)

    NSResponder* aResponder = [[NSResponder alloc] init] ;

    とかいうコードは書けない。エラーが出るかワーニングが出るか鬼が出るか蛇が出るか知らぬがとにかく怒られるはずである。ところがObjective-Cではこのコーディング、通ってしまう。ただこのaResponderというインスタンスがなんの使い道もない「超芸術トマソン」なだけ、なのね。

     想像だが、Objective-Cの設計者に言わせればJavaやC++のようにわざわざこれに「abstract」とか言う識別子をつけさせてコンパイルエラーだのワーニングだの出すのは無駄だということなんだろう。概念をちゃんと理解してるまともなプログラマは、間違っても上のaResponderみたいなインスタンスは作らない。作っちゃうようなプログラマは仕事の邪魔だからほっとけばいいではないの、と。……オレはこの言語のこういうトコが大変好きなんだが、読者諸賢はいかがですか。

     さて話を戻してなんでこんな抽象クラスなんてモノがあるのかというと……それはとってもとっても長い話になるのでまたの機会にするとして(笑)、このNSResponderというクラスを一言で説明すると「イベントハンドリングを行なうクラス」つうことになる。逆にいうとCocoaでは基本的に、このNSResponderのサブクラスでないオブジェクトではイベントのハンドリングは行なえない。

     そして基本クラスのNSViewがどうしてこいつのサブクラスになってるかといえば理の当然、ユーザーが使うボタンだのテキストフィールド、スライダーやスクロールバーといったいわゆるコントロールと呼ばれるもの全てがこのNSViewのサブクラスとしてできているためである(この例外がNSObject直のサブクラスであるNSMenu、そのせいでいくつかのかっこいいMenuがらみの機能がCarbonでは使えてCocoaでは使えない、まぁでもそれもまた別の話だ)。

     すなわちNSViewというクラスのメソッドは、このNSResponderから継承されたイベントハンドリング関係のものと、そのイベントを惹起するところのディスプレイ(表示)を担当するNSView固有のものとに大別できる。まずは見てくれから話を始めた方がとっかかりがいいと思うので、次回から数回をかけて、NSViewの「NSResponderから継承されたんではない」メソッドを説明して行こう。
    (2005_04_14)

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

    UNIXとしてのMac OS X

    〜Perlについて(12)〜

     こんにちは、高橋真人です。
     さて、前回に引き続きPerlに備わっているコードを読みやすくするための仕組みをさらに見ていきましょう。
     前回の最後に触れましたq//もしくはqq//というコーテーションの仕方ですが、Perlではスラッシュはもともと区切り文字として使われます(って、一般的にはスラッシュは区切り記号なわけですが)。なので、ダブル・シングルコーテーションの代用としてのみならず、他にもスラッシュが使われる場面はあるのです。
     Perlでのスラッシュの用途としていちばんポピュラーなのは正規表現です。正規表現はPerlの中でも重要かつ大きな位置を占める技術なので、いずれ改めて解説をします(と、前にも書いた気がする)ので今はさらっと流しますが、正規表現が頻繁に用いられる文字列の検索・置換の処理を例にあげてみます。

    $string =~ s/ABC/def/;

     これがPerlにおける基本的な検索・置換の例です。この式はスカラー変数の$string(この場合は文字列を保持しているという前提)において、ABCという文字並びを見つけたら、それをdefという文字並びに置き換える(ただし一度だけ)という処理になります。
     細かい説明は省きますが、この場合sというのが検索・置換を行う演算子で、構文としては、

    s/検索される正規表現/置き換えられる表現の式/;

    といった形になります。つまり、演算子sのあとに、検索元と置換先がスラッシュで区切られて並ぶわけです。
     ところが、この正規表現(検索対象の表記)の中にスラッシュやらバックスラッシュやらが並ぶと、見た目にうるさいばかりではなく、混乱を招いてバグを作り込んでしまうことが多くなります。
     たとえば、こんなケース。

    $string =~ s/http:¥/¥/¥w+¥.apple¥.com¥///;

     これは、「http://xxx.apple.com/」(xxxの部分は任意)という文字列並びを見つけ出し、空文字列に置き換える、つまりそのまま削除するという処理です。検索対象のスラッシュをエスケープしているのはもちろんですが、任意の単語構成文字を表す「?w」でもバックスラッシュが使われますし、ドット文字は正規表現では特別の役割を持つのでそれを打ち消すためにやはりバックスラッシュでエスケープしてやらねばなりません。
     日本語環境で見ている限り、バックスラッシュは¥マークに見えるでしょうが、欧文で表示すればさらに視認性は落ちるでしょう。これを例えばこんな感じに書き換えることができます。

    $string =~ s#http://¥w+¥.apple¥.com/##;

     ドット文字や「¥w」のエスケープ文字がなくなるわけではありませんが、だいぶ余計な文字が減っているのはお分かりでしょう。
     何が起こったのかはお分かりですね? 区切りのスラッシュがシャープ記号に代わったわけですが、これによりもはやスラッシュは区切り文字の意味を持たなくなったためにエスケープしてやる必要がなくなったということです。
     別に、シャープ記号でなくても構わないのです。何とPerlでは「代用記号」として英数字と空白文字(改行やタブ)以外のものならば何でも使うことができるので、その時々に応じて視認性がより確保しやすい記号を選べばよいのです。

     他の視認性を上げるための手法として、連載の52回目で紹介した「ヒアドキュメント」というやり方もあります。以下のようなものでした。

    print <<EOT;
    <HTML>
         <HEAD>
              <TITLE>MOSA</TITLE>
         </HEAD>
         <BODY>
              $time
         </BODY>
    </HTML>
    EOT

     慣れないと構造が読み取りにくいですが、実際の出力内容は<HTML>から</HTML>までの部分です。
     先頭のprintという演算子に対して、「<<EOT」というものを与えていますが、この「EOT」の部分は、出力の中身に出てこないものであれば、どんなものでも構いません。ちなみに、この例では$timeのところに現在の時刻が保持されているため(連載52回参照)変数が展開されて時刻が表示されますが、代わりに「<<’EOT’」と、終了を示す識別子をprintに与える際にシングルコーテーションで囲ってやるとこの表現全体がシングルコーテーションで囲われているのと同じように変数の展開がされずに「$time」という文字列のままで表示されます。

    ニュース・解説

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

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

    【開発環境】

    Mac OS X 10.4(Tiger)の発売日が無事4月29日に決定しました! これでWWDC2005まで待ちぼうけを食らう心配はなくなり、初期バージョンのバグや仕様の問題点を、バシバシと現地の担当技術者に追求できることになります(笑)。Apple社のWWDCホームページでは、そうした各技術部門の担当チーフも写真で紹介され、毎年恒例のApple Design Awardsの募集も開始されたようです。いよいよWWDC2005開催の雰囲気も盛り上がってきたのですが、参加費の早期割引は4月22日が締め切りですので、まだ参加を申し込んでいない方は期限に注意してください。

    また、こちらも恒例の近畿日本ツーリストによるWWDCツアーの参加者募集も開始されました。マイレージの関係で、MOSAツアーとは別の航空会社の方が良い方は、こちらのツアーを利用されることをお勧めします。今年は、現地でのホテル確保が難しいようですので(何故?)、ツアーを利用することを決めている方は、MOSAツアーおよび近ツリツアーのどちらかを、早めに申し込んでおいた方が無難でしょう。

    近畿日本ツーリストWWDCツアー
    http://ec.knt.co.jp/wwdc2005/

    WWDCとは関係ありませんが、「Unrolling AltiVec, Part 1: Introducing the PowerPC SIMD unit」という題名で、IBMサイトにAltiVecに関する技術解説が登録されました(これがPart 1なのでさらに続く?)。AltiVecに興味ある方は一度覗いてみてください。

    http://www-128.ibm.com/developerworks/power/library/pa-unrollav1/index.html?ca=dgr-mw01AltiVec1

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

    前回から4月15日の期間中、Apple社のDocumentationサイトには新規ドキュメントが17登録されました。ただし、「SMIL Scripting Guide for QuickTime」と「JavaScript Scripting Guide for QuickTime」を除くと、残りはすべてマイナーな改訂版です。また、デベロッパー向けに2つの読み物が登録されています。「Cross-Platform Development with Core Foundation」は、CoreFoundation Frameworkをクロスプラットホームで利用しようと言う内容です。ついでに、Apple社は、CocoaとXcode&Interface BuilderのX86版を開発して販売したらどうでしょうか? iTunesのようのように、両プラットホームでまったく同じ操作方法の良質なアプリケーションが増え、世のため人のためかもしれません(笑)。「Tiger Developer Overview Series:Developing with Core Data」の方は、前号の木下さんの解説がとても参考になります。

    「Accessing Hardware From Applications」DV(PDFあり)
    「Carbon-Cocoa Integration Guide」CB&CO(PDFあり)
    「CGL Reference」OG(PDFあり)
    「Codec Components」QT(PDFあり)
    「Component Manager for QuickTime」CO&QT(PDFあり)
    「I/O Kit Fundamentals」DV(PDFあり)
    「JavaScript Scripting Guide for QuickTime」QT(PDFあり)(初版)
    「The Objective-C Programming Language」CO(PDFあり)
    「Power Manager Reference」CB(PDFあり)
    「QuickTime Initialization Guide」QT(PDFあり)
    「QuickTime VR」QT(PDFあり)
    「SMIL Scripting Guide for QuickTime」QT(PDFあり)(初版)
    「URL Loading System」CO
    「Working With Serial I/O」DV(PDFあり)
    「Writing an I/O Kit Device Drive」DV(PDFあり)
    「Writing Drivers for Mass Storage Device」DV(PDFあり)
    「Mac mini Developer Note」HW(PDFあり)

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

    「Cross-Platform Development with Core Foundation」(読み物)

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

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

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

    前回から4月15日の期間中、新規のテクニカルノートは2つ登録されました。また、新規テクニカルQ&Aの方はひとつだけ登録されています。TN2042の方は、2002年5月に登録された内容の改訂版となっています。TN2130では、作業用メモリを確保するためにMac OS Xで用意されている幾つかのAPIの動作状況を、きちんとケース分けして解説しています。結論から言えば、malloc()とcalloc()を使用しておけば問題は無いようです。

    TN2130「Memory Allocation Recommendations on Mac OS X」
    TN2042「Tailoring Java 1.3.1 Applications for Mac OS X」(2002年11月?)

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

    QA1421「iSight – Configuring gain settings for IIDC cameras」

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

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

    前回から4月15日の期間中、Apple社のSample Codeサイトには、新しいサンプルソースコードがひとつも登録されませんでした。

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

    【デベロップメント SDK】

    前回から4月15日の期間中、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.

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

    2005-04-12

    目次

    • 「WebObjects Dev Report」    第2回   田畑 英和
    • 小池邦人の「Carbon API 徒然草」
    • SqueakではじめるSmalltalk入門  第37回  鷲見 正人
    • ニュース・解説               木下 誠

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

     Tigerの情報も徐々に公開されてきたようで、そのリリースが待ち遠しいですが、6月にはWWDCも控えておりなにが発表されるやら楽しみです。Tiger環境でWebObjectsがどのようにサポートされるかなども情報があきらかになった時点で、この連載を通して取り上げて行きたいと思います。
     サーバ環境はなかなか気軽にバージョンアップできない場合が多く、今でもまだJaguar(10.2)で運用しているシステムもあったりするかもしれませんが、実際にサーバ機のOSをアップデートするとなると一時的にではあるにせよサービスを停止する必要もでてきますし、そういった運用面のこともいずれ取り上げていければと思います。

    まずはプロジェクト名

     さて、プロジェクトを開始するにあたってなにか名前がないことにはどうにも収まりが悪いわけですが、まずはプロジェクト名から決めていきたいと思います。こういった名前を思いつきで適当に決めてしまいますと後になって後悔したり、決めたはいいがプロジェクトの方向性がころころ変わってしまい、最初に決めた名前とはかけ離れたものになってしまった、なんてこともありますが、まずは名前を決めるところから始めてみましょう。
     構想時間3秒で思いついた名前が「WOMatch」です。このプロジェクトではWebObjectsで「ジョブマッチングシステム」を開発することからWO + Matchingということで「WOMatch」になったというわけです。安易な名前付けかもしれませんが、なにより分かりやすい名前ですしXcodeのプロジェクトもこの名前で作成していきたいと思います。
     あと名前を付けるときに注意しなければならないこととして、すでに使われている名前と重複していないかのチェックがあります。特に商品やサービスの名前としても使うような場合は、商標としてすでに登録されていないかなどの確認が必要になってきます。ちなみにGoogleで「WOMatch」を検索してみたところ3件でした。はたして、このプロジェクトはGoogleでひっかかる日がくるでしょうか。

     話題は少しそれてしまいますが、Googleといえば地図サービスのβ版を提供しており、衛星画像の表示機能も加わったようです。住所を打ち込むだけでなんとApple本社のビルまで、バッチリと見れてしまいます。

    ・Google Maps(BETA)
    http://maps.google.com/
    ・Apple本社住所
    1 Infinite Loop, Cupertino, CA 95014

     このGoogle Mapsのサイトにアクセスするとそのレスポンスの良さにすぐ気付くかと思いますが、最近このようなJavaScript等の技術を駆使したサイトが注目を集めており、Ajax(Asynchronous JavaScript + XML)といった言葉も生まれてきています。
     「WOMatch」でこういった技術を取り込んでいけるかどうかはまだ分かりませんが、Flashに頼らずとも既存のWeb関連技術を組み合わせればかなりのことができるようになってきています。Tigerで導入されるDashboardも将来は他のプラットフォームに派生していくことも十分考えられますし、Webの世界もまだまだ進化の余地があるということですね。

    今後の方針

     さて、本題に戻りまして、先日本プロジェクトの今後の方針を決める為にMOSA事務局にて関係者の打ち合せがおこなわれましたのでそちらの報告をしておきたいと思います。
     現在のビジネスマッチングでは主に技術者(あるいは企業)が各自のスキル情報を公開してコンタクトを待つといった使われ方がされていますが、これですとマッチングとしては片方向だけになってしまいますので、まずは逆のパターン、つまり案件の情報を提示して技術者を募集するといった機能を盛り込んでいこうということになりました。
     またその他の機能的なこととしましては、スキル情報だけが掲載されていても実際のところどうなのかよく分からないという問題がありますので、第三者の評価機能も必要になってきます。Yahooオークションの出品者評価あるいはMixiの紹介文といったところでしょうか。ここまできますとソーシャルネットワーク的な要素も加わってくることになり、アクセス権も会員限定の部分と一般に公開する部分とに分かれてくるでしょう。
     さらにはE-mailでの新着情報自動配信ですとか、会員DBの一元化といった課題も上がっています。現在はシステムごとにデータ管理が分かれていますのでそちらを統合することにより、より効率的な運営が可能になるというわけです。

     というわけで今回も概要的な話だけになってしまいましたが、次回からは開発をスタートするにあたってどのような準備をしていけばよいのかといったことを解説していきたいと思います。

    小池邦人の「Carbon API 徒然草」(2005/04/08)

    ドラッグ&ドロップの活用(その1)

     

    Finderからアプリケーションへのアイコン(ファイルやフォルダ)のドラッグ&ドロップは、もうひとつのファイルのオープン方法として、Macユーザの間ではすっかりお馴染みです。今回から数回に分けて、こうしたドラッグ&ドロップ処理のアプリケーションへの実装について解説したいと思います。

    ウィンドウ上へドラッグ&ドロップされたアイコンから情報を得て、そのファイルをオープンするといった処理は、数多くのアプリケーションで採用されています。こうした処理は、Drag ManagerのAPIを使うことで実現します。本サンプルアプリケーションでも、画像ファイルやフォルダ(Finderのアイコン)を直接カタログウィンドウのブラウザ上にドロップすることで、その情報を登録することが可能です。以前、「コールバックルーチンの初期化」を紹介した時にもお話しましたが、ドラッグ&ドロップを利用するには、まずは2つのコールバックルーチン(Callback Routine)をシステムに登録(インストール)する必要があります。それを実行しているのがsetupDrag()ルーチンです。

    void setupDrag(void)
    {
        InstallTrackingHandler( (DragTrackingHandlerUPP)myTrackDrag,NULL,NULL );
        InstallReceiveHandler( (DragReceiveHandlerUPP)myReciveDrag,NULL,NULL );
    }

    コールバックルーチンとは、システムに制御が渡っている間、一時的に制御をアプリ側に戻すためにシステム側から実行されるルーチンのことです。setupDrag()では2つのコールバックルーチンを登録しています。そのうち、InstallTrackingHandler()で登録されているmyTrackDrag()ルーチンは、アイコンをドラッグしている間に継続して呼ばれます。また、InstallReceiveHandler()で登録されているmyReciveDrag()ルーチンは、アイコンをドロップした瞬間に呼ばれます。

    各コールバックルーチンに渡される引数や返り値は、Universal InterfacesのDrag.hに定義されていますので、そちらを参照してください。Mac OS X 10.1から「DragActions」に関係するAPIがいくつか追加されましたが、それ以外の仕組みはMac OS 9の時代からからほとんど変更ありません。以前にも言及しましたが、setupDrag()でコールバックルーチン名の先頭に付けている(DragTrackingHandlerProcPtr)や(DragReceiveHandlerProcPtr)といったキャストは、Mac OS Xネイティブアプリケーションであれば不必要なはずです。しかし、Drag.hの定義内容にミスがあるのか、キャストを記述しないとコンパイルエラーが発生しますので注意してください。

    通常、Drag Managerを利用する場合には、次の3つの処理を実装する必要があります。まずは、ドラッグ最中の処理(Tracking処理)、そしてドロップされたデータを受け取る処理(Receive処理)、最後に自分のデータをドラッグして相手に渡す処理(Send処理)です。本サンプルアプリケーションでは、アプリケーション側のデータを別アプリ(Finderなど)に渡す機能はありませんので、Tracking処理とReceive処理のみを実装します。まずは、Tracking処理の方を見てみることにします。Tracking処理の目的は、ユーザにドロップ可能なターゲット領域(通常は矩形枠)を知らせるために、その領域を強調色(ハイライト色)で表示し直すことにあります。そのためには、ドラッグされているデータ(PICTとかファイル保存場所)が受け取り可なのか不可なのかを判断する必要もあります。以下が、InstallTrackingHandler()でシステムへ登録されたmyTrackDrag()ルーチンです。

    #define  BROW_ID  100     // ブラウザコントロールのID番号
    
    long    d_acc;           // ドラッグデータのドロップを許しても良いかどうか?
    long    d_cnb;           // 強調色で表示されているターゲット領域の矩形番号
    
    pascal void myTrackDrag( DragTrackingMessage mes,WindowPtr window,
                                               long *refcon,DragReference dref )
    {
        Rect    drt[32]; // ターゲット領域は32個まで設定可能(今回はひとつ)
        short   ct;
        Point   pt;
    
        switch( mes )
        {
            case kDragTrackingEnterWindow: // ドラッグがウィンドウ領域へ入る
    
                d_acc=trackDragAcceptType( window,dref ); // 受け取れるデータか?
                d_cnb=0; // ターゲット領域の矩形番号を初期化する
                break;
    
            case kDragTrackingInWindow: // ドラッグがウィンドウ領域内を移動中
    
                if( ! d_acc )
                    break;
                GetDragMouse( dref,&pt,0L );  // ドラッグのマウス位置を得る
                GlobalToLocal( &pt );         // マウス位置をローカル座標に変換
                if( ! trackDragInWindow( window,dref,pt,drt,&ct ) )
                                    // ウィンドウ内にターゲット矩形領域があるか?
                    trackDragDrawHilite( dref,pt,drt,ct ); // あれば矩形枠を強調
                break;
    
            case kDragTrackingLeaveWindow: // ドラッグがウィンドウ領域から外れる
    
                if( d_acc && d_cnb )
                    HideDragHilite( dref ); // ターゲット矩形領域の強調色を元に戻す
                d_acc=0;
                break;
        }
    }
    


    myTrackDrag()では、ドラッグデータの状態が引数で渡されるDragTrackingMessageの値によって判断できる仕組みになっています。メッセージには、kDragTrackingEnterWindow、kDragTrackingInWindow、kDragTrackingLeaveWindowの3種類があり、それぞれドラッグされているデータ(例えばアイコン)がウィンドウ領域へ入った時、ウィンドウ領域内を移動している時、ウィンドウ領域から外れた時に伝達されます。まずは、ドラッグがウィンドウ領域へ入った時に、そのデータが受け取り可能かどうかをtrackDragAcceptType()ルーチンで判断します。

    short trackDragAcceptType( WindowPtr window,DragReference dref )
    {
        FlavorFlags      flag;
        ItemReference    item;
        unsigned short   i,ct;
    
        CountDragItems( dref,&ct ); // ドラッグされているデータの個数を得る
        for( i=1;i<=ct;i++ )
        {
            GetDragItemReferenceNumber( dref,i,&item ); // リファレンス番号を得る
            switch( GetWRefCon( window ) ) // ウィンドウの種類を判断する
            {
                case 'CATA': // ターゲット領域がカタログウィンドウ内の場合
    
                    if( GetFlavorFlags( dref,item,'hfs ',&flag )==0 )
                                     //  データタイプが'hfs 'かどうかチェックする
                        return( 1 ); // これは受け取れるデータである
                    break;
            }
        }
        return( 0 ); // 受け取れるデータはひとつもない
    }
    


    今回はターゲット領域となるウィンドウはカタログウィンドウのみで、それ以外のウィンドウ(画像表示ウィンドウなど)はアイコンドロップのターゲット領域とはなりません。その判断は、GetWRefCon()で得たウィンドウタイプで判断します。ターゲットがカタログウィンドウであれば、GetFlavorFlags()を使いドラッグされているデータの種類が受け取り可能かどうかを判断します。今回はドラッグされているデータタイプが'hfs 'の場合にのみ受け取ることができます。もし、受け取れると判断されれば、trackDragInWindow()により、ターゲット領域を特定します。

    short trackDragInWindow( WindowPtr window,DragReference dref,Point pt,
                                                            Rect drt[],short *ct )
    {
        short        ret=0;
        ControlRef   chd;
    
        *ct=0;
        if( d_acc==1 )
        {
            switch( GetWRefCon( window ) ) // ウィンドウの種類を判断する
            {
                case 'CATA': // ターゲット領域がカタログウィンドウ内の場合
    
                    *ct=1;  // ターゲット領域はひとつだけ
                    getMyControlRef( window,BROW_ID,&chd );
                                          // ブラウザコントロールのControlRefを得る
                    GetControlBounds( chd,&drt[0] ); // ブラウザの矩形枠を得る
                    break;
            }
        }
        return( ret );
    }
    


    ドラッグ&ドロップ処理ではウィンドウ全領域がターゲット領域となる場合が多いのですが(Finderなどがそう)、今回はウィンドウ内のブラウザコントロールの矩形枠が唯一のターゲット領域となります。もし、ウィンドウ内に複数のターゲット領域が存在しているとすれば、外部変数のd_cnbにその識別番号(1から始まる)を記録して強調枠を描いたり削除したりする場合の判断に用います。以下が、ターゲット領域の矩形枠を強調色で描画するtrackDragDrawHilite()ルーチンです。

    void trackDragDrawHilite( DragReference dref, Point pt,Rect drt[],short ct )
    {
        short        i,now=0;
        RgnHandle    rgn;
    
        for( i=0;i<ct;i++ ) // ターゲット領域の個数分ループさせる
        {
            if( PtInRect( pt,&drt[i] ) ) // ドラッグ位置を確認
            {
                now=i+1; // 現在のターゲット領域番号をセット
                break;
            }
        }
        if( now && d_cnb!=now ) // 新しいターゲット領域に入った場合
        {
            if( d_cnb ) // もし前に別のターゲット領域へ入っていれば...
            {
                HideDragHilite( dref ); // 前のターゲット領域の強調色を削除
                d_cnb=0;                // ターゲット領域番号をクリア
            }
            if( rgn=NewRgn() ) // 描画用のRegionを作成
            {
                RectRgn( rgn,&drt[now-1] );   // Regionに矩形枠をセット
                ShowDragHilite( dref,rgn,1 ); // ターゲット領域を強調色で描画
                DisposeRgn( rgn );            // Regionを削除
                d_cnb=now;                    // 現在のターゲット領域番号をセット
            }
        }
        else if( now==0 ) // ターゲット領域から外れた場合
        {
            if( d_cnb )  // もし前に別のターゲット領域へ入っていれば...
            {
                HideDragHilite( dref ); // 前のターゲット領域の強調色を削除
                d_cnb=0;                // ターゲット領域番号をクリア
            }
        }
    }
    


    もし、ターゲット領域をウィンドウ枠ひとつだけに限定すれば、このルーチンはずっと簡単な処理となります。現在のDrag Managerではウィンドウのテーマ(背景)が「しましま」であると、何故だかShowDragHilite()を実行しても強調色で矩形が描画されません(涙)。背景が真っ白なドキュメントウィンドウならOKなのですが、「しましま」テーマであっても何らかの強調を行うのが、ユーザインターフェースガイドライン的には正しいと思うのですが....。

    次回は、Finderからドラッグされてきたアイコンがターゲット領域(ブラウザ)へドロップされた瞬間の処理、つまりInstallReceiveHandler()で登録されているmyReciveDrag()について解説したいと思います。

    つづく

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

     本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回は、再びプロトコルに話を戻し、コレクションの探索を続けます。

     まずは、ダブルディスパッチにからめて、飛ばしたadaptingプロトコルについてちょっとだけ。

     adaptingプロトコルには、前回登場した#adaptToCollection:andSend:の他に、#adaptToNumber:andSend:、#adaptToPoint:andSend:、#adaptToString:andSend:が定義されています。それぞれに対応するクラス(Number、Point、String)かそのサブクラスに属するインスタンスがレシーバとなる二項演算メッセージにおいて、その引数がコレクションだった場合の対処方法が記述されています。それぞれのメソッドの定義を見て、次に示した式の結果について予想がつくかどうかで、ダブルディスパッチを理解できているかを確認してみるのもよいでしょう。

    4 * #(1 2 3)       " => #(4 8 12) "
    (4 @ 5) * #(1 2 3) " => #(4@5 8@10 12@15) "
    '456' * #(1 2 3)   " => #(456 912 1368) "

     adding、arithmeticは済んでいますね。comparingプロトコルは飛ばします。

     次のconvertingプロトコルには、コレクション間の相互変換のためのメソッドがまとめてあります。原則として単項メッセージセレクタで、asの後に変換したいコレクションクラス名が続きます。

    #(2 2 3 4 1 4 2 1 4) asBag   " => a Bag(1 1 2 2 2 3 4 4 4) "
    #(2 2 3 4 1 4 2 1 4) asSet   " => a Set(1 2 3 4) "
    #(2 2 3 4 1 4 2 1 4) asOrderedCollection
                  " => an OrderedCollection(2 2 3 4 1 4 2 1 4) "
    #(2 2 3 4 1 4 2 1 4) asSortedCollection
                    " => a SortedCollection(1 1 2 2 2 3 4 4 4) "
    'smalltalk' asArray  " => #($s $m $a $l $l $t $a $l $k) "
    'smalltalk' asBag    " => a Bag($k $l $l $l $m $a $a $s $t) "
    'smalltalk' asSet    " => a Set($k $l $m $a $s $t) "
    'smalltalk' asOrderedCollection
          " => an OrderedCollection($s $m $a $l $l $t $a $l $k) "
    'smalltalk' asSortedCollection
            " => a SortedCollection($a $a $k $l $l $l $m $s $t) "
    


     変換と言っても、レシーバのクラスが変更されるわけではなく、レシーバをもとに、指定した種類のコレクションが新しく作られることに注意してください。

     ところで、新しくコレクションを作るには、この変換作業のほかに、作りたいコレクションが属するクラスに直接メッセージを送る方法もあります。オーソドックスには、まずnewを送信して空(から)のコレクションを作り、それに「add: anElement」などのメッセージを送って要素を追加してゆきます。

    | collection |
    collection _ OrderedCollection new.
    collection add: 3; add: 2; add: 2; add: 1.
    ^ collection  " => an OrderedCollection(3 2 2 1) "
    
    | collection |
    collection _ Set new.
    collection add: 3; add: 2; add: 2; add: 1.
    ^ collection  " => a Set(1 2 3) " "重複排除"
    
    | collection |
    collection _ SortedCollection new.
    collection add: 3; add: 2; add: 2; add: 1.
    ^ collection  " => a SortedCollection(1 2 2 3) " "ソート済み"
    


     なおこの方法は、要素を増減させることができないコレクション(配列や文字列など)には使用できません。

    Array new add: 3; add: 2; add: 2; add: 1 " => error "

     この種のコレクションの場合には、たんにnewするのではなく、「new: size」で必要なサイズのコレクションを用意してから、あらためて各要素を置き換える手続きが必要です。

    | array |
    array _ Array new: 4.
    array at: 1 put: 3.
    array at: 2 put: 2.
    array at: 3 put: 2.
    array at: 4 put: 1.
    ^ array   " => #(3 2 2 1) "

     要素が六つより少ないなら空のコレクションを作らずに、いきなり「with: anElement」、「with: element1 with: element2」、「with: element1 with: element2 with: element3」…というメッセージを送信して済ませることもできます。

    OrderedCollection with: 3 with: 2 with: 2 with: 1
                         " => an OrderedCollection(3 2 2 1) "
    Set with: 3 with: 2 with: 2 with: 1   " => a Set(1 2 3) "

     newしてから要素を追加するのと違って、この方法は配列や文字列にも使えます。

    Array with: 3 with: 2 with: 2 with: 1   " => #(3 2 2 1) "
    String with: $c with: $b with: $b with: $a  " => 'cbba' "

     要素が六つより多いときは、いったん要素を配列などに収めてから#withAll:で渡します。

    OrderedCollection withAll: #(3 3 3 2 2 1 1 1 1)
                       " => an OrderedCollection(3 3 3 2 2 1 1 1 1) "
    Set withAll: #(3 3 3 2 2 1 1 1 1)             " => a Set(1 2 3) "

     以上のようにクラスが受信を許すメッセージと、それによって起動されるメソッドについては、ブラウザの上段の左から二番目のペインの下にある、classボタンをクリックして閲覧モードを切り換えた後、instance creationプロトコルを選択することで、一覧したり、定義を見ることができます。

    [fig.A]ブラウザでクラスプロトコルを閲覧しているところ。
    http://squab.no-ip.com:8080/mosaren/uploads/37a.png

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

    ニュース・解説

    今週の解説担当:木下 誠

    ----------------------------------------------------------------------
    Core Dataを解説するドキュメントが公開
    ----------------------------------------------------------------------

    Appleが、Tiger Developer Overview Seriesの最新作、「Developing with Core Data」を公開していました。ついに、Core Dataの全貌を表すドキュメントの公開が始まりました。Core Dataは、Cocoa Bindings以来の、Cocoaアプリケーションにやってきた大きな変革の波です。同時に、EOF (Enterprise Objects Framework)で培われた技術の、復活の狼煙でもあります。

    Core Dataは、いままでCocoaフレームワークに欠けていた、モデルやストレージ周りのサポートを提供するものです。具体的には、アプリケーションで使うデータモデルのデザインとその管理、データのストレージへの保存と読み書き、アンドゥとリドゥのサポート、などが含まれます。

    つまり、アプリケーションのMVC (Model-View-Controller)アーキテクチャの、モデル部のサポートとなります。これにより、ビューのサポートを行うNSViewクラス階層と、コントローラのサポートを行うCocoa Bindingsと合わせて、CocoaのMVCモデルは一つの完成を見た、といえるでしょう。

    また、Core DataはWebObjectsのEOFに強く影響を受けており、EOFの復活と見ることも出来ます。このドキュメントでも、WebObjectsとの関係に言及しています。ただし、WebObjectsの、汎用的なデータベースアクセスフレームワークとしての側面は、Core Dataには取り入れられていません。データベースを必要としない、一般的なCocoaアプリケーションでも使える技術、という方向性を強調したいようです。

    TigerのXcodeでは、Core Dataのためのデータモデリングツールが搭載されます。これは、アプリケーションで使うデータモデルをグラフィカルに編集するツールで、UMLでのクラス図のような図でオブジェクトグラフを表示します。このモデリングでは、エンティティ、属性、関係、プロパティといった、データベースやモデリングの分野で馴染みの深い言葉が登場します。

    Core Dataで利用するクラスをいくつか紹介しましょう。エンティティをアプリケーションで実現するクラスとして、NSManagedObjectが実装されます。エンティティが持つプロパティは、NSManagedObjectによって管理され、KVC(Key-Value Coding)や、KVO (Key-Value Observing)で、アクセス、管理されます。つまり、Cocoa Bindingsと相性がいいということになります。そして、NSManagedObjectの集合は、NSManagedObjectContextによって管理されます。このクラスは同時に、エンティティの変化を監視することで、アンドゥ、リドゥのサポートも行います。NSManagedObjectContextとストレージの間を取り持つのが、NSPersistentStoreCoordinatorです。このクラスは、ストレージに保存されたデータと、メモリ上に展開されるオブジェクトの橋渡し役になります。

    また、データモデルはInterface Builderとも統合されています。Appleお得意のゼロコーディングとして、Xcode上のモデリングツールから、Interface Builder上のウィンドウに、データモデルをドロップすることで、そのモデルを表示、編集するためのGUIが作成されます。Core Dataの機能を紹介するデモとして、非常に効果が高いです。

    最後に余談ですが、Core Dataを表すアイコンが作られたようです。ストレージの中から、青い透明の球体がのぞいている絵です。Tigerのテクノロジのキーワードの一つは「Core」で、Coreを表すアイコンとして、内部からのぞく透明の球体が使われているようですね。

    Developing with Core Data
    http://developer.apple.com/macosx/tiger/coredata.html

    ----------------------------------------------------------------------
    OCUnitのチュートリアル
    ----------------------------------------------------------------------

    Appleが、「Test Driving Your Code with OCUnit」というドキュメントを公開していました。Objective-Cのユニットテストを行うフレームワークである、OCUnitの使い方を解説した、チュートリアルです。

    モサ伝を読んでいる方なら、ユニットテストのことはご存知でしょう。むしろ、日々の業務で使っている方もいると思います。言語毎にいろいろなユニットテストのためのライブラリ、フレームワークがありますが、Objective-CのためのフレームワークがOCUnitです。

    OCUnitの特徴は、Xcodeと統合されていることです。どういうことかというと、テストの結果をXcodeの警告、エラーウィンドウで表示することが出来ます。ということで、Objective-Cでのユニットテストを行う必要がある方は、目を通しておくと便利なドキュメントです。

    ちなみに、Xcodeでの警告、エラーの表示は、テキストを読み込んで表示しているので、スクリプトで整形してやれば簡単に表示できるようです。

    Test Driving Your Code with OCUnit
    http://developer.apple.com/tools/unittest.html
    Sen:te - OCUnit
    http://www.sente.ch/software/ocunit/

    ----------------------------------------------------------------------
    WWDC 2005関連情報
    ----------------------------------------------------------------------

    「Meet the Engineers Behind Tiger」とうページが公開されていました。WWDCで説明をしてくれる、Appleのエンジニアやマネージャが紹介されています。写真がずらりと、あまりフォトジェニックとは言えませんが、並んでいます。

    また、Apple Design Awardsの受付も始まっているようです。

    WWDC 2005 - Meet the Engineers Behind Tiger
    http://developer.apple.com/wwdc/engineers.html
    WWDC 2005 - Apple Design Awards 2005
    http://developer.apple.com/wwdc/ada/

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

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

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

    2005-04-05

    目次

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

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

    はじめに

     皆様あらためましてこんにちは! 前回まで「Behind the WebObjects」のタイトルでWebObjectsの解説をおこなってきました田畑です。予告どおり今回から内容を切り替えて新しい連載を始めることになりました。よろしくお願いします。
     とはいいましてもあいかわらずWebObjectsをテーマにしていくのですが、これまでは様々な技術を個別に解説してきたのに対し、これからは実際に1本のアプリケーション(2本3本と増えていくかもしれませんが)を開発しながらその過程を逐次この連載で紹介していきます。そんなわけでしてタイトルのほうは「WebObjects Dev Report」と名付けました。

     WebObjectsのもつ機能を利用すればデータベースアクセスなど様々なことが実現できますが、実際にアプリケーションを開発するとなると色々なことを考慮していく必要があります。システム構成をどうするだとか、要件分析をおこなうだとか、設計、テスト、ドキュメント作成、場合によってはトレーニング、保守運用なども必要になってきます。
     こういったことをすべてこの連載で網羅するには限界がありますが、まずは「実運用に耐えうるアプリケーションをいかにして開発していくか」という実践的な内容を目標に連載を進めて行きたいと思います。連載をとおして実際にアプリケーションを開発していくわけですから、現場で発生する様々な問題を取り上げていくことになりますので、WebObjectsで開発をおこなっている方々、あるいはこれから開発を始めてみようと考えている方々に対してなるべく有益な情報を提供していくことができればと考えています。

    ジョブマッチングシステム

     どういったアプリケーションを開発していくかですが、「ビジネスマッチングシステム」の開発をおこなっていきます。MOSA会員の方々はご存知かと思いますがMOSAのWebサイト上ではビジネスマッチングサービスがおこなわれています。

    ・MOSAビジネスマッチングシステム
    http://www.mosa.gr.jp/htmdocs/service-teikyo-bizmatch.htm

     ここではMOSA会員がジョブスキルを登録・公開することにより、企業・人とのマッチングをおこない、ビジネスのサポートをおこなっています。具体的にはMOSA会員資格をもった方が開発経験などのスキルシートを登録し、その情報を会員・非会員にかかわらずどなたでも閲覧できるようになっています。
     登録者へのコンタクトを希望する場合はMOSA事務局が仲介をおこない、その後は双方で話を進めていくというのが現状のスタイルになっています。情報を登録できるのはMOSA会員に限定されていますが、公開されている情報は誰でも閲覧することができます。

     今回はこのビジネスマッチングシステムをWebObjectsを使ってリニューアルしていくのがテーマになります。現状のシステムをもとにシステムの概要を分析してみますと、ユーザ別に考えた場合は以下のようになります。

    ・情報提供者
      ユーザ:MOSA会員
      役割:スキルシートを登録し情報を公開
    ・閲覧者
      ユーザ:誰でも
      役割:公開情報を閲覧し仲介のうえ情報提供者にコンタクト
    ・仲介者
      ユーザ:MOSA事務局 
      役割:コンタクト希望者と情報提供者との仲介など

     これらのシステムを今後リニュアールしていくことになります。具体的にどこまで細かくレポートできるか模索しながら連載を進めていくことになるかと思いますが、ソースコードの公開も含めなるべくオープンな形で進めていければと思います。

    WWDC2005

     話題が変わりまして、今年もApple社の開発者向けConference「WWDC」が開催されます。すでに参加を検討されている方は概要をご存知かと思いますが、会場は今年もサンフランシスコで6/6-10の日程で開催されます。ここ数年、残念ながらWebObjects関連のセッションは減少傾向にあり、なんといっても新しいニュースがないのが不安材料でしたが、現在公開されているセッション内容をみてみますとなにやら期待できそうな内容が掲載されています。内容についてはぜひ直接こちらをご覧になってください。

    ・WWDC2005 Enterprise ITトラック一覧
    http://developer.apple.com/wwdc/descriptions/desc-enterpriseit.html

     というわけで、今回から新連載が始まりました。連載も隔週から毎週に増えることになり、なるべく実践的で有益な情報をどんどん発信していければと思いますので読者の皆様よろしくお願いします。

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

     NSApplicationの話もこれが最後。アプリケーションが終了するときの話である。前回(あれ、前々回だっけ?)起動のときに書いたように、Nibファイルで定義しインスタンシエートしたオブジェクトはアプリケーションが起動されるとメモリ上にその場を与えられ、IBOutletやIBActionといったコネクションが確立されたところで awakeFromNib というメッセージを受け取る。
     例えばここに、ダイアログボックスを通して……なんでもいいがそのアプリに関する設定をおこなうオブジェクトがあるとする。このオブジェクトがawakeFromNib を受け取ると、NSUserDefaults のクラス・メソッドstandardUserDefaults を呼び出し、そこから前回ユーザーが行なった設定を読み込んでそれをダイアログボックス上に再現する。あるスイッチがオンだったのならそれに対応するチェックボックスの state をオンに設定するというようなことだ、わかるよね? つまり初期設定の読み込みはこのタイミングでできる。では逆に初期設定を保存するのは?

     実はここが今回のミソなんだが、awakeFromNib のタイミングで初期設定を読み込むのならそのオブジェクトが破棄されるとき、つまり dealloc を呼ばれたときに書き込めばいいんぢゃないかと思うわけだ。え、そうですかって?思わないヒトもいるかも知れないけどオレは最初そう思ったんだよ。
     ところが、だ。これもあんまり……というか今までオレが読んだCocoaに関する本にはちゃんと書かれていたことがないのだが、この dealloc というメッセージ、送ってもらえるオブジェクトとそうでないオブジェクトがあるのである。上の例に出てきたダイアログボックスを使うオブジェクトなんか、たいがいは dealloc を送ってもらえず、なんでユーザーの設定が保存されないんだろうとプログラマが首を傾げるタグイである。

     あんまりもったいぶっててもしょうがないのでタネ明かしをしてしまうと、アプリケーションの起動とともにNibファイルから読み出され、アプリケーションの終了以外では(まぁプログラムがわざわざ明示的にそれをやってれば別なんだが)その破棄がおこらないオブジェクトには、アプリの終了時にイチイチdeallocを送らない、ということである。
     こう言ったら解りやすいかな、例えばあなたが壊れたパソコンを破棄するとき、いちいち部品をばらばらにして破棄したりはしないでしょ? それと同じ、そもそもdealloc の目的はメモリの解放だから、それを含んでいるアプリ全体の使用域がご破算になるのにチマチマと個々のオブジェクトに解放メッセージを送るのは時間の無駄ってこと、なんだよ。

     それぢゃ初期設定はいつ書き換えればいい? そのタイミングは状況によって2つ考えられる。簡単なのは上の例のようにアプリの稼働中に開閉されるダイアログの場合、ダイアログのオープンが要求されたら初期設定を読み込み、閉じるときに書き込めばいい。しかしそうはいかないオブジェクトもあるよね、アプリが稼働している限り出ずっぱりのウィンドウの CustomViewとか……。
     そこで、お馴染みNSApplicationの登場だ。ユーザーがアプリ終了のオペレーションを行なうと、NSApplicationはそのdelegateに対してapplicationWillTerminate: というメッセージを送ってくる。これを受け取ったdelegate オブジェクトが、初期設定を保存する必要のあるオブジェクトたちにそれを行なうためのメッセージを送ればいい。簡単でしょ?

     やぁやれやれ、やっとこれでNSApplicationの概説はおしまいである。次回からは次なる大物、NSViewを取り上げて、Cocoaにおけるイベントハンドリングの実際を解説して行こうと思っている。御用とお急ぎでないかたは引き続きご愛読をよろしく。
    (2005_03_31)

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

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

     こんにちは、高橋真人です。
     さて、前回の最後に「コードを読みづらくする要素」を余り使わずに記述するところもPerlのメリットだ、ということを申しました。Perlのこの辺のところは、「ちょっとやり過ぎ」の観があるくらいに徹底しています。
     例として、以前紹介した以下のようなコードを使いましょう。

    print ‘Hello’ if (/^$/);

     これは、変数$_の中身が空文字列の場合にHelloと出力するというものですが、この条件がひっくり返った場合にはどうなるかと考えてみます。

    print ‘Hello’ if (! /^$/);

     もちろん、このように否定演算子を使って条件をひっくり返してやれば済む話です。少なくともCの場合ならば。そして、これはPerlにもちゃんと当てはまります。ところが、Perlではこの条件をひっくり返す代わりに何とunlessというものが用意されています。
     これを使うと上の文は、

    print ‘Hello’ unless (/^$/);

    となります。つまり、$_が空でない場合にHelloと出力するということになるわけです。
     ちなみにCでもよく使われる「!」という否定演算子ですが、これはかなり目立たない記号ですよね。C++ではこれと同等の予約語としてnotというのを使えることになっているので、私はC++を書く時には必ずと言っていいほどこちらを使うのですが、このnotはPerlにもあるのです。
     だから、別にわざわざunlessなどというものを作らなくても、

    print ‘Hello’ if (not /^$/);

    で充分じゃないか、と私は思うんですけれどもね。
     ところで興味深いことに、if節を後置にした場合にはこんな書き方をしているのに、Cと同様にif節を前置にした場合、Perlではブレースを省略できません。つまり、

    if (/^$/) print ‘Hello’;

    という書き方は、構文エラーとなってしまうのです。確かに、Cではif分を多段的に使った場合に、elseとの対応関係がおかしくなってしまうので、「必ずブレースを付けるようにしよう」というような流儀もあったりしますが、Perlではこれを強制するわけです。このように、先ほどのunlessにしても今の話にしても、Perlの個性的な部分は好き嫌いを生み出しそうな要素ですね。
     こんなところにも、作者の人となりを色濃く反映していると思うのは私だけではないと思います。もっとも、Larry Wall氏(Perlの作者)を知っているわけではないのですけれども。

     さて、読みにくさを排除しようとするPerlの書き方はまだまだあります。
     前回話題にしたダブルコーテーションとシングルコーテーションの話でよく出てくるのは、囲った記号と同じものが文字列中に出てきたケースという話で、開きと閉じに同じ記号を使う場合には、それらの呼応関係がおかしくならないようにしなければならないわけです。こんな時、一般にはエスケープ文字というのを使うのはご存知の通りです。

    print “Hello ¥”brave¥” world!¥n”;

     こんなふうに、braveという単語を囲むダブルコーテーションを「閉じ記号」と誤認識させないためにエスケープ文字「?」を使うわけですが、文字列がやたらと長くなったり、エスケープするものがやたらに増えてきたりすると、これはなかなか見づらくなってくるわけです。
     Perlではこんな時のために「コーテーションの別の書き方」が用意されています。上記のコードは以下のように書くことができます。

    print qq/Hello “brave” world!¥n/;

     つまり”"をqq//で置き換えてしまえるのです。ちなみに”の代わりにはq//というのを使えます。

    ニュース・解説

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

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

    【開発環境】

    巷では、「Mac OS X 10.4(Tiger)が4月中には発売になるのでは…?」という噂が囁かれております。だとすると、WWDC2005期間中には10.4.1がシードできるくらいの順調な開発ペースですね(笑)。そんな中、Apple社のサイトにおいて、WWDC2005で開催される数多くのカンファレンス・セッションの内容が明らかになりました。

    http://developer.apple.com/wwdc/descriptions/

    毎年、当日でないと内容が明らかにされないセッションも幾つかあるのですが(昨年はTiger発表前だったのでその数が多かった)、今年は既にTigerが出ているでしょうから、そうした「秘密セッション」の数は少なそうです。今回の内容をざっと眺めてみたところ、筆者が注目している「Graphics and Media」系セッションはわずか7つしかないのに(OpenGL関連はたった2つ)、「Enterprise IT」系セッションは32もあります!こうして見ると、Apple社がターゲットとしているWWDC参加者の分野(職業)が、年々大きく変化して来ていることが理解できます(まだiPod関係は含まれていないが…)。

    「今年は日本語同時通訳が無い!」という不安な話も持ち上がっていますが、例年以上に充実したセッションを期待したいと思います。

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

    前回から4月1日の期間中、Apple社のDocumentationサイトには新規ドキュメントがひとつも登録されませんでしたが、デベロッパー向けに2つの読み物が登録されました。前号で木下さんが紹介されている「Optimizing OpenGL Data Throughput on Mac OS X」は、アプリケーションからOpenGL APIを使う場合の最適化方法の解説です。同様な内容は、テクニカルノートのTN2093「OpenGL Performance Optimization : The Basic」でも詳しく解説されています。「最適化が必要なのは、我々よりもあなた達(ビデオカードメーカ&Apple社)の方が先でしょ!」と、デベロッパーから不満の声が聞こえて来そうですね…(笑)。

    「Test Driving Your Code with OCUnit」(読み物)

    http://developer.apple.com/tools/unittest.html

    「Optimizing OpenGL Data Throughput on Mac OS X」(読み物)

    http://developer.apple.com/graphicsimaging/opengl/optimizingdata.html

    前回から4月1日の期間中、新規のテクニカルノートはひとつも登録されませんでしたが、テクニカルQ&Aの方は4つ登録されています。QA1414では、アイコンにフォーカスリング(青い縁取り)を描画させる方法が解説されています。Tigerでは256×256ピクセルのアイコンが表示可能になるという噂がありますが、さてどうなんでしょうか?QA1418については、前号の木下さんの解説も参考にしてください。

    QA1409「Disappearing Help content」
    QA1414「Defining and Using the kTransformFocused IconTransformType」
    QA1418「How can I add the ability to read and write Keynote 2 documents to my application?」
    QA1412「Using ConvertMovieToFile or ConvertMovieToDataRef to convert movies without displaying the settings dialog」

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

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

    前回から4月1日の期間中、Apple社のSample Codeサイトには、新しいサンプルソースコードが3つ登録されました。「CarbonSketch」は、Mac OS X 10.3と最新Xcodeに対応させた修正バージョンです。「TypeServicesForUnicode」の方は、随分と古くからあるサンプルソースコードなのですが、HIViewとCarbon Eventに対応して見事に復活しました。「MemoryBasedBundle」については、前号で木下さんが紹介されています。

    「CarbonSketch」(Carbon関連)
    「TypeServicesForUnicode」(ATSUI関連)
    「MemoryBasedBundle」(Bundle関連)

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

    【デベロップメント SDK】

    前回から4月1日の期間中、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.