MOSA Multi-OS Software Artists

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

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

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

MOSADenバックナンバー 2004年11月発行分

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

    2004-11-30

    目次

    • SqueakではじめるSmalltalk入門  第20回  鷲見 正人
    • 小池邦人の「Carbon API 徒然草」
    • 「Behind the WebObjects」    第32回  田畑 英和

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

     本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回は、残された“払い戻し”メソッドを定義してBankAccountを完成させます。

    メソッド#withdraw:は、基本的に#deposit:と逆、つまりパラメータの値を#balanceの返値から差し引く…という挙動を示せばよいので、メッセージパターン(あるいはメソッド名)を「deposit:」から「withdraw:」に、メソッド中の計算の「+」を「-」に置き換えさえすれば、とりあえずは動きます。

    deposit: aNumber
    self balance: self balance + aNumber

         ↓

    withdraw: aNumber
    self balance: self balance – aNumber

     ただこれだけではつまらないので、self balanceの結果が負にならないようにする制約を設けましょう。負にならないようにする方法はいくつか考えられます。ちょうどよい復習になるので、実際にコードをいろいろと考えてみてください。

    一番単純なのは、前述メソッドに、「self balanceが負なら、self balanceが0になるようにする」というメッセージ式を付け加える方法。既出のメッセージの組み合わせで記述できるはずです。

    withdraw: aNumber
      self balance: self balance - aNumber.
      self balance < 0 ifTrue: [self balance: 0]

     メソッド本体は追加した式を含めて2行になります。Smalltalkでは式の区切りは「.」(ピリオド)であることを思い出してください。改行は原則としてスペース以上の意味を持ちません。1行目の終わりのピリオドを入れ忘れるとaNumberにselfというメッセージを送る式と解釈されてしまいます。さらに、前の行のselfに対する「balance: … ifTrue: …」というメッセージを送信する、2行全体がひとつのメッセージ式であると判断されてしまいます。もちろん、#balance:ifTrue:などというメソッドは定義されたことがないので、コンパイラが気を利かせてスペルチェッカを起動します。

    [fig.A]1行目の終わりのピリオドを忘れたときの様子
    http://squab.no-ip.com:8080/mosaren/uploads/20a.png

     ピリオドや括弧の括り忘れは、このようにスペルチェッカの起動により気付かされることが多いです。スペルチェッカが、単純なスペルミスではなく、見慣れないメソッド名を指摘してきたらよく注意して勘違いや書き損じがないかコードをよく見直すべきでしょう。

    他にも、self balance - aNumberの結果を一時変数に束縛しておく手があります。

    withdraw: aNumber
      | newBalance |
      newBalance _ self balance - aNumber.
      newBalance > 0
        ifTrue: [self balance: newBalance]
        ifFalse: [self balance: 0]
    


     Smalltalkでは、制御構造もメッセージ式で表現し、同時にそれは“文”ではなく“式”なので返値を持ちます。したがって、まったく同じ挙動を次のように書き換えることもできます。

    withdraw: aNumber
      | newBalance |
      newBalance _ self balance - aNumber.
      self balance: (newBalance > 0 ifTrue: [newBalance] ifFalse: [0])

     レシーバとパラメータを比較して大きなほうを返値とする#max:というメソッドを知っていれば、一時変数も不要になり、式自体ももっとシンプルにできそうです。

    withdraw: aNumber
      self balance: (self balance - aNumber max: 0)

     さあ、これでBankAccountは完成です。当初のスクリプトが期待通りに動作するか確かめてみましょう。

    | account |
    World findATranscript: nil.             "transcriptを開く"
    account _ BankAccount new.              "a BankAccount作成"
    account balance: 1000.                  "1000円預金"
    Transcript cr; show: account balance.   "残高照会 => 1000 "
    account withdraw: 600.                  "600円払戻"
    Transcript cr; show: account balance.   "残高照会 => 400 "
    account deposit: 60.                    "60円預入"
    Transcript cr; show: account balance.   "残高照会 => 460 "
    account withdraw: 700.                  "700円払戻"
    Transcript cr; show: account balance.   "残高照会 => 0 "

    お詫びと訂正:第15回の上のスクリプトの出力結果(コメントの内容)が間違っていました。正しくはここに示したとおりです。申しわけありません。

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

    小池邦人の「Carbon API 徒然草」(2004/11/26)

    データブラウザ・コントロールの初期化

    今回は、setupCatalogWindow()から呼ばれているsetupDataBrowser()とその関連ルーチンを調べてみます。サンプルアプリケーションのメインウィンドウには、ファイル一覧を表示するためのデータブラウザ(Data Browser)コントロールが配置されています。まずは、それを初期化するための作業から解説します。

    データブラウザとは、Carbon FrameworkのControl Managerに属し、何らかのデータ一覧をウィンドウ上でリスト表示やカラム表示するためのコントロールです。Finderのウィンドウではファイルやフォルダの一覧をリスト表示していますが、その時に使われているのがこのコントロールです。昔はToolBoxのList ManagerというAPI群を用いていましたが、最近ではこちらを使うのが主流です。データブラウザは純粋なコントロールなのですが、その機能を本格的に活用しようとすると、通常のコントロール(ボタンやチェックボックスなど)には存在しない複雑な処理をソースコードで記述する必要があります。

    このデータブラウザを扱うためのAPI群ですが、Control Managerの中でも特にMacintosh開発者泣かせの代物でした。その第一の理由は、随分最近まで正式な解説ドキュメントが存在していなかったためです。なんと! テクニカルノートの2009番(現在はLegacyドキュメントに分類)が一番詳しい解説書であり、それのみに頼って開発するしか方法がありませんでした。そのテクニカルノートに「実装済み」と記述されている機能でも、使用してみると実に不安定で(使えるのか?使えないのか?よく分からなかった...)、加えてMac OS Xに移行した時の処理速度の遅さは尋常ではありませんでした。Mac OS X 10.0や10.1でのFinderのリスト表示の遅さを記憶されている方も多いでしょう(笑)。

    データブラウザは、Mac OS X 10.2(Panther)が登場して、やっとまともに使えるようになったわけです。そして2004年の3月、待ちに待った2つの解説ドキュメントがApple社のDeveloperサイトに登録されました。そのうちの「Displaying Data in a Data Browser」には、データブラウザの使い方とそのサンプルソースが載っています。もう片方の「Data Browser Reference」では、関連しているAPIがすべて個別に解説されています。データブラウザ関連のAPIが定義されているUniversal Interfacesは、ControlDefinitions.hとControls.hです。アプリケーションの開発でデータブラウザを十二分に活用したい方は、こちらも参照してみてください。

    「Displaying Data in a Data Browser」(PDFあり)

    http://developer.apple.com/documentation/Carbon/Conceptual/display_databrowser/index.html

    「Data Browser Reference」(PDFあり)

    http://developer.apple.com/documentation/Carbon/Reference/databrow_reference/index.html

    アプリケーションの開発では、ソースコード内でAPIを記述し、ダイレクトにデータブラウザを作成することも可能です。しかし、通常はボタンなどのコントロールと同様に、Interface Builderで雛形を作成してNibファイルとして保存しておきます。今回は、縦スクロールバーを持ち、テキスト用のカラムが2つあるリスト表示形式のデータブラウザを用意しました。この2つのカラムには、データブラウザに登録する画像ファイルの「ファイル名」と「ファイルタイプ」を表示することになります。カラムとは、Finderのリストウィンドウ上部で「名前」「変更日」「サイズ」などに分けられている領域のことです。カラムには、テキストの他にアイコン、時間、メニュー、チェックボックス、プログレスバー、なども表示できるのですが、今回はそれらを使用しません。後から個々のカラムを認識するためには、それぞれのカラムに識別子として4バイトのProperty ID(今回は'name'と'type')を設定しておく必要があります。

    この前処理により、Nibファイルからウィンドウが作成された時点でデータブラウザも作成、配置されます。後はそれを初期化するのですが、その作業をsetupCatalogWindow()から呼ばれているsetupDataBrowser()が実行しているわけです。

    #define    BROW_ID    100     // データブラウザのコントロールID
    
    short setupDataBrowser( WindowRef window )
    {
        ControlRef              browser;
        short                   ret=1;
        DataBrowserCallbacks    call;  //  コールバックルーチンセット用の構造体
    
        getMyControlRef( window,BROW_ID,&browser ); // ブラウザのControlRefを得る
        call.version=kDataBrowserLatestCallbacks;   // コールバックのバージョン設定
        if( ! InitDataBrowserCallbacks( &call ) )   // コールバックルーチンを初期化
        {
            call.u.v1.itemDataCallback=mySetGetItemData; // データ表示用コールバック
            call.u.v1.itemNotificationCallback=myNotification; // 連絡用コールバック
            SetDataBrowserCallbacks( browser,&call ); // 2つのコールバックをセット
            ret=0;
        }
        return( ret );
    }
    


    getMyControlRef()ルーチンでは、データブラウザのID番号(100)を指定することで、そのControlRefを得ています。この仕組みを使うためには、Interface BuilderのInfoダイアログで、先んじてコントロールのSignatureとIDを設定しておく必要があります。メインウィンドウのデータブラウザには、Signatureに'MosA'、IDに100が設定されています。続いて、InitDataBrowserCallbacks()でデータブラウザ用コールバックルーチンを初期化し、SetDataBrowserCallbacks()で2つのコールバックルーチン(mySetGetItemData()とmyNotification())を登録しています。

    データブラウザは、リストデータの表示や変更、ブラウザ上で起こったマウスイベント処理など、それぞれの目的に応じたコールバックルーチンを持つことでユーザの操作に対処する仕組みとなっています。そのため、目的に応じた数多くのコールバックルーチンを独自に登録する必要があるわけです。以下が、ControlDefinitions.hに定義されているコールバックルーチン登録用のDataBrowserCallbacks構造体です。現時点では10種類のルーチンが登録可能ですが、今回はこのうち、itemDataCallbackとitemNotificationCallbackの2つだけを使用します。残りのDrag&DropやContextual Menuの操作を担当するルーチンについては使用しないので登録する必要はありません。

    struct DataBrowserCallbacks {
      UInt32      version;
    
      union {
        struct {
          DataBrowserItemDataUPP  itemDataCallback;
          DataBrowserItemCompareUPP  itemCompareCallback;
          DataBrowserItemNotificationUPP  itemNotificationCallback;
    
          DataBrowserAddDragItemUPP  addDragItemCallback;
          DataBrowserAcceptDragUPP  acceptDragCallback;
          DataBrowserReceiveDragUPP  receiveDragCallback;
          DataBrowserPostProcessDragUPP  postProcessDragCallback;
    
          DataBrowserItemHelpContentUPP  itemHelpContentCallback;
          DataBrowserGetContextualMenuUPP  getContextualMenuCallback;
          DataBrowserSelectContextualMenuUPP  selectContextualMenuCallback;
        }        v1;
      }        u;
    };
    


    登録する2つのコールバックルーチンのうち、itemDataCallbackの方へ代入するルーチンは、リスト表示させるデータをシステムへ与える(セット)処理と、変更されたデータをシステムから得て(ゲット)アプリケーションで再保存するための処理を担当します。また、itemNotificationCallbackへ代入するルルーチンの方は、データブラウザ上で発生した各種イベント(データ選択やクリック、キー入力など)の処理を担当しています。

    次回は、DataBrowserCallbacks構造体に代入してSetDataBrowserCallbacks()で登録した2種類のコールバックルーチン、mySetGetItemData()とmyNotification()について詳しく解説したいと思います。

    つづく

    「Behind the WebObjects」  第32回  田畑 英和

     今年の湘南ミーティング無事終了しました。WebObjectsのセッションに参加していただいた方々ありがとうございます。ここ数年は毎年WebObjectsのセッションを担当してきましたが、はたして来年はどうなることでしょう。
     次期Mac OS X(Tiger)ではEOFの再来ともいえるCore Dataが搭載されることになっていますので、適切な次期がきたらこの連載でも取り上げてみたいと思います。

    さて、湘南ミーティングではカスタムEOの生成方法やテスト手法について解説しましたが、今回はカスタムEOの実装方法について取り上げてみたいと思います。

    カスタムEOの初期化

     まずはカスタムEOの初期化について解説します。EOを新規に作成したときに特定のアトリビュートを初期化したい場合があります。例えばカスタムEOを作成した日時を設定するとか、nullを許可していないアトリビュートになにか適切な値をデフォルト値として設定するなどの処理が考えられます。
     通常オブジェクトの初期化をおこなうにはコンストラクタの利用が考えられますが、カスタムEOの場合コンストラクタに初期化のコードを記述してはいけません。例えばカスタムEOのMovieクラスに以下のようなコードを実装したとしましょう。

    public class Movie extends EOGenericRecord {
    
         public Movie() {
             super();
    
             setRevenue(new BigDecimal(0));
         }
    }
    


     このコンストラクタでは、オブジェクトが生成されたときに"revenue"アトリビュートを初期化しています。たしかにEOを*新規*に追加する場合はこれでよいのですが、このコンストラクタはEOを新規に追加したときだけではなく、データベースから既存のレコードを取得してEO化したときにも呼び出されます。
     ですので、既存のレコードにまでコンストラクタで初期化処理をおこなってしまうと、データを上書きしてしまうことになります。
     EOを新規に追加するたびに以下のようなコードを実装してもよいのですが、これでは同様のコードを何カ所でも実装することになり、毎回同じ初期化処理をおこなうには効率的ではありません。

         Movie movie = new Movie();
         session().defaultEditingContext().insertObject(movie);
         movie.setRevenue(new BigDecimal(0));

    新規追加時の初期化

     そこでEOCustomObjectクラス(EOGenericRecordの親クラス)にはEOを新規に追加する場合にのみ呼び出される、以下の初期化用メソッドが用意されています。つまりカスタムEOの内部に初期化処理を埋め込むことができるのです。

    ・新規追加時の初期化メソッド
    public void awakeFromInsertion(EOEditingContext ec)

     このメソッドは、EOをEditingContextに追加する時に呼び出されますので、既存のレコードをEO化したときには呼び出されません。このメソッドを利用すると初期化のコードは以下のように書き換えることができます。このときまず親クラスのawakeFromInsertion()を呼び出すように実装してください。

    public class Movie extends EOGenericRecord {
    
         public Movie() {
             super();
         }
    
         public void awakeFromInsertion(EOEditingContext ec) {
             super.awakeFromInsertion(ec);
    
             setRevenue(new BigDecimal(0));
         }
    }
    

    既存データの初期化

     またデータベースから取得したデータをEO化したときにのみ呼び出されるメソッドも用意されています。このメソッドを利用すればデータベースからデータを取得するたびに、任意の処理を適用することができます。

    ・既存のデータの初期化メソッド
    public void awakeFromFetch(EOEditingContext ec)

    まとめ

     カスタムEOのコンストラクタはEOを新規に追加する場合と既存データからEOを作成する場合の両方で呼び出されるため初期化の処理には不適当です。そこでEOCustomObjectクラスで用意されている初期化のメソッドを用いることになります。初期化用のメソッドはEOの新規追加用と、既存のデータ用の両方が用意されています。
     さらに初期化処理を工夫するには、初期化用のデータをPropertiesファイルから読み込む方法や、EOModelerのEOEntity UserInfo Inspectorで設定した値を読み込む方法などが考えられます。状況に応じて初期化の値を動的に変更するようなケースも考えられますが、このような処理をおこなうには独自に対応する必要があります。

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

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

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

    2004-11-24

    目次

    • SqueakではじめるSmalltalk入門   第19回  鷲見 正人
    • 藤本裕之のプログラミング夜話 #57
    • 高橋真人の「プログラミング指南」  第56回
    • 湘南ミーティング 2004 レポート        高橋 政明
    • ニュース・解説

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

     本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回は遅延初期化についてです。

    前回、生成した直後のオブジェクトa BankAccountがメッセージ「deposit: 100」に正しく反応できないことに(いささかわざとらしく…)気が付き、そのとき表示されるノーティファイアが提供する情報から、数値の束縛が期待されるインスタンス変数balanceにnilが束縛されていたことが原因だということも分かりました。したがって、インスタンス変数balanceに数値を(アクセッサを介して)束縛しておくことで、消極的ではありますが、とりあえずこの問題は解決できそうです。

    | account |
    account _ BankAccount new.
    account deposit: 100   "=> ノーティファイア "

       ↓

    | account |
    account _ BankAccount new.
    account balance: 0    "インスタンス変数balanceに0を束縛"
    account deposit: 100  "エラーは出ない"
    ^ account balance     "=> 100 "

     ただ、これではおもしろくないので、アクセッサにひと工夫することにより別の方向から、よりスマートに、この問題を解決する方法を模索してみることにします。今、BankAccount >> #balanceの定義は、

    balance
    ^ balance

    と、単純にインスタンス変数balanceを返すだけです。これを「もしbalanceがnilなら、balanceに0を束縛して、あらためてそれを返値とする」…というような遅延初期化を行なうコードに置き換えてしまえば、このメソッドを介してインスタンス変数balanceにアクセスする限り、nilが返ることはなくなります。では、実際にコードを書いてみましょう。

    balance
    ^ balance ifNil: [balance _ 0]

     1行目はメッセージパターン(パラメータがないので、メソッド名とも一致)なので変わりません。なお、ブラウザのコードペインでは、メソッド名が既存のものと同じメソッドの定義は、断りなく古いものと置き換わります。バージョンは管理されているので、ファイルの重ね書きのような気の使い方をする必要はありません。

    メソッド本体は2行目です。まず、行頭の「^」は無視して考えましょう。改めて書き直すとこうなります。

    balance ifNil: [balance _ 0]

     初出の#ifNil:で腰が引けてしまうかたもあるかもしれませんが、この式は典型的なメッセージ式です。インスタンス変数balanceに束縛されているオブジェクトに「ifNil: …」というメッセージを送ることを表わします。ここで起動されるメソッド#ifNil:はレシーバがnilならパラメータとして添えられたブロック(手続きのオブジェクト)を評価してその結果を返し、そうでなければレシーバを式の返値とします。したがってこの場合、balanceにnil以外が束縛されていれば、balanceに束縛されているオブジェクトがこの式の返値になり、balanceにnilが束縛されている場合は、ブロックが評価されてその値がこの式全体の返値になります。

    ブロックの内容である「balance _ 0」は、インスタンス変数balanceに0を束縛する代入式です。Smalltalkはメッセージ式ですべてを表現するのが原則ですが、代入式は例外でこのように書きます。ただ、Smalltalkにおいて代入の手続きは“式”なので返値があります。それは、変数に代入(束縛)しようとするオブジェクトで、くだんの代入式では「0」がこれにあたります。

    改めてまとめると、この式は、インスタンス変数balanceにnil以外が束縛されているときはそのオブジェクトを、nilが束縛されているときはbalanceに改めて0を束縛し、同時に0を返す式…となります。さらに頭に「^」が付いていたので、この式の返値がそのままこの#balanceメソッド(と言っても、メソッドにはこの式しかないのですが…)の返値になります。

    このようなBankAccount >> #balanceの改変により、以後生成するa BankAccountはもちろん、すでに存在するインスタンスについても、そのインスタンス変数balanceが未定義か否かに関わらず、メッセージ「deposit: 100」への応答は正常に行なわれるようになるでしょう。これにて一件落着ですね。

    一般に遅延初期化という手法は、アクセス頻度の低いプロパティ(インスタンス変数)を多数抱えるオブジェクトで、生成時の初期化のコストを削減しパフォーマンスを稼ぐために用いられるのが普通です。しかし、Smalltalkのように動的な(つまりシステムを止めずに動かしながら改変を加えることが多い)システムでは、すでに運用中のオブジェクトに対し、インスタンス変数やアクセッサを比較的安全に追加できる…というメリットが加わります。

    次回は最後のメソッド#withdraw:を追加して、このBankAccountを完成させます。

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

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

     えーと、今回は「カッコをつける話」をしたい。実はこないだのモサ湘南ミーティングのセッションでタカハシマコトさんが「Cocoa……というよりObjective-Cが嫌いなヒトはあのカッコが嫌だっていうんですね」みたいな話をしたんだよな。もちろん嫌だってヒトにカッコはいいぞカッコはいいぞこれからはカッコの時代だぞカッコを使わないと取り残されるぞみたいな脅迫的宗旨替えを迫る気持ちはこれっぽっちもないんだが、この種のカッコ嫌いの中には相当数の食わず嫌いも混入しているのではないかと思い、ちょっとこのカッコについてちょっとその効用を説明してみようかなと。

    昔懐かしいニコラス・ビルト先生考案のPASCALという言語にはプロシージャとファンクションというもんがあった。プロシージャは値を戻さないサブルーティン・コール、ファンクションは結果として値を戻すサブルーティン・コールのことだ。で、ご存知かと思うがCやC++には元々この区別は無かった。PASCALの仕様を口を極めて罵ったブライアン・W・カーニハン先生は「呼び出された側が何を戻そうとそれを使うかどうか、見るかどうかは呼び出した側の勝手である」という考えに基づいてCを設計、ANSIが void型というのを採用するまで、戻り値の型が明示されていないサブルーティンは int型を返すという暗黙の了解もあったくらいなのだ。
     いや、ここで言いたいのはそういうANSIによるC言語のPASCAL化(だってそうでしょ? 最初カーニハンたちはこのテの融通の利かなさを批判してたはずなのだ)の是非ではなくて、「Cでは全てのサブルーティン・コールが『ファンクション(関数)』であり、値を持っている」ことの方なのだ。……あっと、厳密に言って、void型を「返す」モノが関数か? という疑問はないではないけど、その尻はANSIに持って行ってくれ。
     たとえばだ、「strcat()」という有名なファクションのプロトタイプ宣言(これが必要になったのもANSI以来である)は確か以下のようになっている(手持ちの「ANSI C言語大辞典」による)。

    char *strcat(char *string1, char* string2);

     この関数は戻り値としてstring1へのポインタを返す。したがって以下のようなコーディングが可能だ。

    printf ("The result of concatination = %s n", strcat(string1, string2));

     さらに、

    printf ("The result of concatination = %s n",
            strcat( strcat(string1, string2), strcat(string3, string4)));

     さらに事態をエスカレートさせれば、 

    printf ("The result of concatination = %s n",
            strcat( strcat(string1, string2), strcat(string3, string4)),
            strcat( strcat(string5, string6), strcat(string7, string8)) );

     まだまだ入れ子にすることが可能である。で、あなた今、「ああややこしい、だからカッコは嫌いなんだよ」と思ったでしょ? でもそれは誤解なのだ。このコードが見にくいのは実はカッコのせいぢゃない。以下のように書いたらどうだね?

    printf ("The result of concatination = %s n",
                strcat(
                    strcat(string1, string2),
                    strcat(string3, string4)
                ),
                strcat(
                    strcat(string5, string6),
                    strcat(string7, string8)
                )
          );
    


     ね、コトはカッコのせいではなく、「{ }」と「( )」の記述のしかたに関するあなたの手癖というか習慣のせいである。「{ }」ではこういう風に書いてへーきなヒトが「( )」をこう書けずに見にくいなどと愚痴をこぼすのは自分が悪いのだ。

     誤解を解いたところで次回からは積極的にカッコを売り込んで行こうと思う。乞うご期待。
    (2004_11_17)

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

    UNIXとしてのMac OS X

    〜Perlについて(2)〜

     こんにちは、高橋真人です。
     さて、Perlは最初はテキスト処理を目的に作られたというようなことを聞いたことがありますが、実際Perlにはテキスト処理をするための豊富な仕組みが備わっています。
     かつてMacOS 9の時代にはMacPerlという便利なツールがあって、テキスト処理のためのドロップレットが簡単に作れてしまうので大変重宝したものです。幸いにも現在のMac OS X上でもClassic環境を使えば問題なく使えるのですが、Perlのバージョンが少し古いところ(日本語版:5.2ベース、英語版:5.6ベース)が残念なところです。
     ご存知のようにMac OS Xには最初からPerlが装備されていますから、Terminalを起動するだけでPerlは使えます。ただ、MacPerlの快適な環境に慣れてしまった身にとっては、コマンドラインのみでの作業はつらいものがあります。こういう方にとってお勧めなのがAffrusというツール。
     これは、ScriptDebuggerというAppleScriptのデバッグツールを発売しているLate Night Software社の製品で、現在のバージョンではMacPerlのようなドロップレットを作る機能こそありませんが(将来できると嬉しいのですね)、MacPerlの弱点だったエディタ機能も充実していますし、何よりもソースデバッガが備わっているためにまるでIDE上で開発作業を進めるような快適さでPerlスクリプトのコーディングができます。
     オープンソースであるPerlの関連製品としては珍しく市販の製品で、ダウンロード販売の価格が99ドルとなっていますが、30日間全機能を試してみることの可能なデモ版も用意されていますので、興味のある方はトライしてみることをお勧めします。

    http://www.latenightsw.com/affrus/index.html

     ついでに無料で使える製品がないかと探してみましたが、今話題のEclipseには案の定Perl対応のプラグインも作られているようです。epicというのがそれですが、Mac OS Xへの対応状況は不明です。

    http://e-p-i-c.sourceforge.net/

     さて、MacOS 9時代にもある程度本格的なテキスト変換処理をMacPerlで作ったことはありましたが、私にとってMacPerlのいちばんの用途はC/C++でのコーディングの際の補助ツールとしてのものでした。
     いくつか例をご紹介したいと思いますが、せっかくですからまだMacPerlをお持ちでない方もこの際入手されてみることをお勧めします。Classic環境上で何の問題もなく使えるはずです。

    http://world.std.com/~habilis/macjperl/MacJP5.j.htm

     起動して、新規書類を開いたら、そこに打ったスクリプトをすぐに実行できます。保存すらしなくてもコマンド+シフト+Rでアクティブなウインドウのスクリプトが実行できる手軽さが「補助ツール」として極めて役に立ってくれるのです。
     実際の使い方に関しては追って解説していきますが、まずは以下のように打ち込んで、コマンド+シフト+Rで走らせてみましょう。

    print A..Z;

     次回はこのスクリプトをきっかけにして、もう少し細かく見ていきたいと思います。

    湘南ミーティング 2004 レポート   高橋 政明

     11月12日金曜日13日土曜日の二日間「第11回 Macintosh Software Meeting in 湘南2004(通称:湘南ミーティング)」が開催されました。
     ここ数年と同じく今年の湘南ミーティングも一日目の午後に初台オペラシティタワーにあるアップルコンピュータ株式会社のセミナールームでスタートしました。昼過ぎに受付を済ませ抽選会用の写真を撮影し、あらかじめ席に置かれた分厚い配布資料を受け取ります。

    【アップルセッション】

     アップルセッションは来日中のI/Oテクノロジーエバンジェリストによる『I/Oセッション』と質問と要望を伝える『フィードバックセッション』それに『Dashboardセッション』の三つです。このセッションはApple Developer Connectionメンバー向けで具体的な内容は残念ながら守秘義務対象のため書けません。『I/Oセッション』は逐次通訳が付き、MacだけでなくiPodなどを含めいろいろなお話を聞く事ができました。また『Dashboardセッション』はちょうどコンテストの始まったDashboardについて日本語での解説を聞く事ができました。

    Apple Dashboard Widget Contestの情報はこちらです

    http://developer.apple.com/macosx/tiger/dashboard/index.html

     葉山の湘南国際村センターへ2台の貸切バスで移動しました。今年は都内の渋滞もさほどではなく順調でした。さらに湘南国際村センター近くのトンネルが開通していて、逗子市内の混雑に影響されず快適でした。バスの車内では交流のきっかけを作るため参加者自己紹介を行っています。はじめて参加された方も多く、UNIX畑の方の参加もすっかり定着したようです。ご家族での参加もありました。

    【初日夜】

     ほぼ予定通り立食パーティがはじまり、おなかが落ち着いた頃に抽選会です。各社および講師らから提供されたたくさんの景品を例年通り顔面ルーレットで抽選します。顔写真を撮影した参加者全員に何かが当たります。この抽選にはいつも小池さんの作ったソフト(トトマック)を使っていましたが、今年はOpenGLセッションのサンプルを兼ねたMac OS Xネイティブバージョンでキーノートのエフェクトのように顔写真が回転しました。
     なお顔面ルーレットのルーツは大谷さんです。最初はQuickTimeプレーヤーを使い、デジカメで撮影した静止画を貼付けて行き、それをループ再生していたのだそうです。(そのためにPowerMac8100本体を会場に持って来られていました)まず景品を決め止まったとき表示していた人が当たり、のシンプルなルールも伝統です。
     iPod miniが5本をはじめ、ハードウェア、パッケージソフト、書籍、アップルグッズ、さらにその他のグッズ〔^_^;〕など豪華で多彩でした。書籍の著者に直接会えるのも湘南ならではです。
     新庄さんから差し入れの林檎もとてもおいしかったですね。

     テクノロジーライターでMOSA理事でもある大谷さんのキーノートセッションは、今年も盛りだくさんでした。窓ガラスや机をスピーカ−に変えるグッズや、プラスチック素材製の水に強い本などを持参していただきました。注目すべきソフトのデモや、届いたばかりのiPod photoの使いこなしをいち早くご披露いただくなど『目から鱗』の楽しいひとときでした。

     キーノートの後は私の担当する「Xcode使いのためのCVS入門」セッションでした。少人数で膝を突き合せるような場を予想していたのですが、深夜にも関わらず(Xcodeでソースコード管理を利用するための情報が少ないためか)多くに方に参加していただき驚きました。UNIXとCVSに精通されている方も多く参加している方に助けていただきながらセッションを進める事ができました。★なおこのセッションの配布資料に誤りがありました。「コンソール」と書いた部分はすべて「ターミナル」です。コンソールではコマンドを入力できません、ターミナルと読み替えてください。

    CVSセッションを終えた後オールナイトセッション会場に戻ると例年よりも多くの方が残っていた印象です。そのためかお酒がなくなるのは早かったようですが、かなり盛り上がっていた事は間違いありません。お酒が適量だったので情報交換が進んだのかもしれません。

    【二日目】

     二日目は3つのトラックに分かれ合計9セッションに加えアップルスペシャルセッションと充実しておりました。全員参加できたアップルセッション以外は配布資料を解説します。

    アップルスペシャルセッションはWWDRのShaan Pruden氏による「Apple Update」。残念ながら通訳なしでしたが、プレゼン画面がわかりやすく密度の高い1時間でした。(こちらの内容も守秘義務対象のため公にできません)

    藤本さんの「AppleScriptで駆動可能なCocoaアプリを作る」セッションは配布資料にプロパティリストとソースがあり、貴重なサンプルとなりそうです。

    田畑さんの「Behind the WebObjects Live!!」セッションは41ページに及ぶ配布資料が圧巻です。データベースのインストールからモデル、フレームワーク、テストの解説などが続きます。フレームワークの多言語化の説明もあります。

    小池さんの「Mac OS X環境におけるOpenGL」セッションはOpenGLの情報源や開発ツールの紹介がありサンプルソースコードが載っています。さらに来年の予告まであり!

    長久さんの「Javaゲームプログラミング」セッションはデスクトップ上でのJava、ゲームプログラムのしくみ、ゲームプログラミングの実際の三部構成です。「市場の分析」や「プログラムと人間」などのトピックもあります。

    木下さんの「Web Kitプログラミング解説と、その実例としてのシイラプロジェクト紹介」セッションは現在プレゼンデータが公開されています。
    http://homepage.mac.com/mkino2/backnumber/image/2004_11/ShiiraAtMOSA.pdf
    Web Kitとシイラ紹介、Web Kitプログラミング入門、シイラプロジェクトの三部構成でスライド枚数は88もあります。

    中野さんの「HID Managerを使ったゲームコントローラの活用と実装」セッションは「予備知識」と「プログラムへの実装」の二部構成です。入力デバイスとしてのゲームコントローラーをアプリケーションから利用する方法がサンプルコードの詳しい解説とともに記されています。

    長野谷さんの「軟派のためのプログラミング環境「AppleScript」解説 最新動向と可能性の限界に迫る!」セッションは「AppleScriptとは何か?」「AppleScriptの最新動向」「可能性を探る」の三部構成で、AutomatorなどTigerの公開されている機能を含め解説されています。

    佐藤さんの「Mac OS X Server 10.3」セッションは、Mac OS X Server 10.3の新機能、10.3で可能になった機能、期待されるフィードバックの三部構成です。(この資料は参加者に連絡したURLからダウンロード可能)普段目にする事の少ない設定画面なども載っています。

    高橋真人さんの「PowerPlant X 入門〜CoreFoundation から、Cocoa との融合まで〜」セッションはCoreFoundationの利用例、STLの参考書籍リスト、PowerPlant Xサンプルソースコード、Cocoaとの融合の詳しい設定とサンプルソースがあります。高密度の配布資料です。

    「より広範囲な応用分野に接する!」がテーマの今年の湘南ですが、あっと言う間に過ぎてしまいました。英語でのセッションが二つもあった事も特徴です。講師の平均年齢も若返ったと思うのですがどうでしょう〔^_^;〕? 二日目の昼休みに恒例の記念撮影を行いました、近くMOSAのwebに掲載されると思います。

    今年参加できなかった方も来年はぜひ抽選会の賞品のため余裕のある大きめの鞄を持参し、夜更かしに耐えられるよう体調を整えて、参加してください!

    ニュース・解説

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

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

    【開発環境】

    Mac OS X 10.3.5に潜んでいた様々な不都合を改善した10.3.6が登場しました。筆者の手元にある複数のシステムHDにもインストールし動作確認をしてみたところ、80Gの外付けFireWire HD(随分古いタイプ)のみ、Mac OS Xのシステムブートが出来なくなってしまいました。もちろん10.3.5までは可能だったのですが、アップデート後は起動時のAppleマーク表示状態でストップしてしまいます。Macintoshのトラブル関連を網羅しているサイトを色々と覗いてみたところ、この問題以外にもHDのマウントすら出来なくなったケースがあるようです。こちらの症状に関しては、HDメーカ各社がFirmwareのアップデートを開始したようで、徐々に問題も収束しているようです。ところが、うちのHDの場合にはシステムブートしようとしなければ何の問題もなくマウントできます。色々調べた結果、FinderからHDのボリューム情報を表示し「所有権とアクセス権:」に表示される「このボリューム上の所有権を無視する」のチェックを外した後、ディスクユーティリティでアクセス権の修復を行うと、再びシステムブートが可能になりました。何故こうなったのかは謎のままですが(よくあること…)、まあ直ってしまえば問題ありません(笑)。

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

    前回から11月19日の期間中、Apple社のDocumentationサイトには新規ドキュメントが13登録されました。初版のドキュメントは「Darwin Notification API Reference」と「Message Framework API Reference」のみで、後はマイナーな改訂版です。デベロッパ向け読み物としての解説も3つ登録されています。「Optimizing Your Application with Shark 4」では、CHUD 4.0(Computer Hardware Understanding Development Tools)に含まれるパフォーマンス・チューニング(最適化)ツールの「Shark 4」を利用したアプリケーション最適化の事例が紹介されています(必見)。「Working with Spotlight」では、Mac OS X 10.4(Tiger)に搭載されるデスクトップ検索システムの「Spotlight」について、今までになかった詳細な解説を読むことができます。

    「Apple Human Interface Guidelines」(PDFあり)
    「Darwin Notification API Reference」(初版)
    「Design Concepts」
    「HeaderDoc User’s Guide」(PDFあり)
    「Java 1.4 Development for Mac OS X」(PDFあり)
    「Kernel Programming」(PDFあり)
    「Mac OS X Frameworks」
    「Message Framework API Reference」(初版)
    「Pasteboard Manager Reference」(PDFあり)
    「System Configuration Programming Guidelines」(PDFあり)
    「Writing PCI Drivers」(PDFあり)
    「QuickTime Overview」(PDFあり)
    「Initializing QuickTime」(PDFあり)

    「Using Java Studio Creator on Mac OS X」(読み物)

    http://developer.apple.com/java/creator.html

    「Optimizing Your Application with Shark 4」(読み物)

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

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

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

    前回から11月19日の期間中、新規のテクニカルノートがひとつだけ登録されました。「Idling Movie Importers」はQuickTime関連のテクニカルノートで、アイドリングを必要とする「Movie Importer Componet」(MovieでないデータやファイルをQuickTime Movieファイルへと変換するためのモジュール)の作成の方法が解説されています。新しいテクニカルQ&Aの方は4つ登録されました。「Sending an Email」については、前号の新居さんの記事を参考にしてください。

    TN2111「Idling Movie Importers」

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

    QA1388「Symbol to Library in GDB」
    QA1386「Core Audio & Xcode – Ensuring the latest Core Audio Headers are installed」
    QA1084「Sending an Email」
    QA1167「Using Interface Builders NSOpenGLView or Custom View objects for an OpenGL application」

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

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

    前回から11月19日の期間中、Apple社のSample Codeサイトには、新しいサンプルソースコードが6つ登録されました。このうちCarbonアプリケーション開発者に速効で有用なのは「AppleScriptRunner」でしょう。アプリケーション内からAppleScriptを実行し、ターゲットとなるモジュールにそれを実行させるためのサンプルコードです。自動でMailにメールを送信させたり、スピーチシンセサイザーを使いテキストを朗読させるような仕組みを参考にすることができます。

    「AppleScriptRunner」(AppleScript関連)
    「MachPortDump」(Mach Port関連)
    「DumpVolumeInfo」(File Volume関連)
    「Fiendishthngs」(Component Manager関連)
    「CryptNoMore」(Security関連)
    「VideoHardwareInfo」(CoreGraphics&OpenGL関連)

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

    【デベロップメント SDK】

    前回から11月19日の期間中、Apple社のSDKサイトには新しいSDKが3つ登録されました。「iTunes COM for Windows SDK」の新版は、iTunes 4.7 for Windowsの発表に合わせた改訂のようです。

    「CoreAudio SDK v1.3.3」
    「iTunes COM for Windows SDK」
    「Kernel Debug Kit 10.3.6」(for Mac OS X 10.3.6)

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

    また、デベロッパー向けツールとしてCHUD(Computer Hardware Understanding Development Tools)4.0.1の配布が開始されました。Mac OS X 10.3.6に準拠したDarwinの新しいソースコードの配布も開始されています。

    「CHUD Tools 4.0.1」(Computer Hardware Understanding Development Tools)

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

    「Mac OS X 10.3.6 (Darwin 7.6)」

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

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

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

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

    2004-11-09

    目次

    • “関西オープンソース2004”レポート(後編)村上幸雄★MOSA会員専用★
    • SqueakではじめるSmalltalk入門  第18回  鷲見 正人
    • 小池邦人の「Carbon API 徒然草」
    • 「Behind the WebObjects」    第31回  田畑 英和
    • ニュース・解説
    MOSA会員専用記事

    “関西オープンソース2004”レポート(後編) ビッツ有限会社 村上幸雄

     開催場所:大阪産業創造館
     日  時:2004年10月22日(金)〜23日(土)
    http://k-of.jp/

     前回に引き続き、関西オープンソース2004のレポートの後編をお届けします。

    Cocoa勉強会in関西

     Cocoa勉強会in関西は、昨年10月から横浜を中心に開催されていたCocoa勉強会を大森智史氏が関西での代表となって開催することになった、関西版の第一回こけら落とし勉強会です。勉強会は22日と23日の両日開催され、22日は関西版代表の大森氏が「AppleEventの送信」を23日はモサ伝ではお馴染みの新居氏が「Cocoa Bindings について」というタイトルで講演されました。
     前者はTechnical Note TN2045の情報を参考にして、gdbでAESend()が送信する電文を確認し、確認した電文をAEBuildAppleEvent()で送信するという内容でした。後者では、実際にCocoa Bindingsを使用したプログラムを作成してCocoa Bindingsの仕組みを確認するといった内容でした。

    PHP-BOF:フレームワークを使ったWebアプリケーション開発

     MapleというオープンソースのPHPフレームワークの紹介です。
     Mapleは、出演者の高橋邦彦氏が、社内向けに開発したPHPのフレームワークをベースに、高橋氏のプライベートな時間と環境で開発されたようで、社内向けのソフトウェアから発展してきたというお話は、オープンソースと企業活動の関係の上手くいった事例として興味深いものでした。
     Maple ProjectのホームページのURLは以下のとおりです
    http://kunit.jp/maple/

    Appleはもう一度ブレークするか? -Macコミュニティの現在/過去/未来-

     新居雅行氏と大谷和利氏、MACお宝鑑定団のDANBO氏、MUGNETの山村和久氏の四名がパネラーとして、AppleとMacコミュニティーの歴史を語るという内容でした。HyperCardやKnowledge Navigator、OpenDoc、Cyberdogなどの懐かしいお話が聴けて、期待通り楽しめました。

    コミュニティブース:WideStudio

     WideStudioは統合開発環境で、開発者の平林俊一氏がブースを担当されていましたので、開発の裏話や、WideStudioの内部について、詳しく聞くことができました。WideStudioは現在では平林氏の勤務先の事業の一環として扱われるようになりましたが、当初はプライベートな時間と環境を利用して開発されていましたので、例えば、仕事が夜の12時に終わるのに、それから帰宅して開発するといった苦労もあったようです。
     WideStudioの内部のお話をいたしますと、GUI部品は独自に実装しています。つまり、プラットフォームに依存しないGUIアプリケーションが開発できます。具体的には、四角を描画する描画ルーチンや、C++のnew演算子等のプラットフォームに依存する部分を移植すれば、そのプラットフォームでWideStudioのアプリケーションが動作するようになるそうです。
     WideStudioのアプリケーションが動作する環境にはT-Engineのような組み込みシステムもあります。また、WideStudioの開発環境はMac OS Xにも対応しています。したがいまして、今まで、Mac OS Xで組み込みシステムのアプリケーションを開発する事例は少なかったと思いますが、WideStudioを利用すれば、Mac OS Xで組み込みシステムを開発することが可能となります。

    コミュニティブース:オープンメール環境(OME)

     OMEは、Mac OS Xで利用できるオープンソースのメールソフトで、コミュニティの代表は新居さんです。私もこのコミュニティに参加しています。
     OMEのコミュニティのメンバは、全国に散らばっていますので、このようなイベントのときでないと、実際に逢うことはありません。そういう訳で、関西オープンソースは関西在住のメンバと逢える、良い機会となっています。

    ステージ

     ステージは3F展示会場と4Fの関西コミュニティ大決戦の会場の二カ所に設けられていました。内容は多種多様なのですが、その中で私の面白いと思ったのは以下のステージです。

    ・突撃インタビュー1号

     Microsoftの楠正憲氏への突撃インタビューです。
     Microsoftのエンジニア全員がVisual Studioを使用している訳ではなく、あるエンジニアの開発環境を覗いたところ、~(チルダ)がついているソースファイルもあったとか、Virtual PCを使用して、仮想マシン環境で動作しているWindowsをデバッグする実演等、裏話から技術的なお話まで聞くことができました。

    ・Samba日本語版開発裏話

     日本Sambaユーザ会の三浦広志氏と白井隆氏が、Samba日本語版開発の裏話や技術的な問題の説明、外国の技術者との共同作業で発生した苦労話を発表するという内容で、特に、日本人でも複雑なために敬遠される日本語処理の問題を外国の技術者に理解してもらうという大変な問題に、いかに対処したかという裏話は、Sambaの恩恵を受けている私としては頭が下がりました。

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

     本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回はノーティファイアで表示される情報の読み方を取り上げます。

    メソッド#deposit:が定義された今、a BankAccountは、「deposit: 100」というような預金額を模した数値をパラメータに持つメッセージを受け取って期待される動きをすることができるようになりました。これは前回、インスペクタで束縛しているa BankAccountで確認しています。ただ、このチェックには、ちょっとした落とし穴があります。たとえば、あらためて、どこか適当な場所で、

    BankAccount new deposit: 100

    をdo it (cmd-D)してみましょう。別のBankAccountのインスタンスを作り、それに「deposit: 100」を送信しているだけです。結果、俗に“エラー”と呼ばれるノーティファイア(ピンクの横長のウインドウ)が現われて処理は中断してしまうはずです。

    [fig.A]ノーティファイア
    http://squab.no-ip.com:8080/mosaren/uploads/18a.png

     なぜ、このようなことになるのかをノーティファイアに表示される情報をもとに、解明してみましょう。

    まず、BankAccountに送信されるnew、その結果返されるa BankAccountに改めて送られる「deposit: 100」も、いずれも不正なメッセージでないことについてはよろしいかと思います。では、なにゆえエラーが起こったのか。そのヒントとなる情報がノーティファイアのタイトルバーに表示されています。

    MessageNotUnderstood: UndefinedObject>>+

     これは、UndefinedObject(のインスタンス)は、#+(というセレクタを含むメッセージ)を理解できません…という意味です。UndefinedObjectのインスタンスは、nilです。nilは、UndefinedObjectの唯一のインスタンスです。つまり、BankAccountに対する「new」か、その返値に対する「deposit: 100」というメッセージ送信の結果、派生的に生じるメッセージ送信カスケードのどこかで「nil + …」という式が評価されたことが分かります。もちろん、あやしいのは我々が定義した後者ということになりますが、ノーティファイアにより提示された情報からも、それを確認することができます。

    ノーティファイアのウインドウ内部、デバッガ起動などのための3つのボタンを用意したペインの下のリストに目を向けてみましょう。各行は、このノーティファイアを表示するまでに送信されたメッセージの履歴を表わしています。Squeakを含めたSmalltalkシステムは、一般に、バイトコードを実行することで動作し、そのバイトコードインタープリタにはスタックマシンが使われています。このリストは、その各スタックに積まれたコンテキスト(インタプリタの内部状態)の一覧、というふうに解釈することもできます。いずれにせよ、今のところは、どういう経緯でノーティファイアの表示に至ったのかを、このリストで簡単に把握できるというふうに考えておけばよいと思います。

    UndefinedObject(Object)>>doesNotUnderstand: #+
    BankAccount>>deposit:
    UndefinedObject>>DoIt
    Compiler>>evaluate:in:to:notifying:ifFail:
    


     余談ですが、同様の情報を含んだものがノーティファイアの起動と同時に、仮想イメージと同じフォルダにSqueakDebug.logとして出力されています。Squeakシステムを維持できない致命的な障害を生じさせてしまったときは、いったん環境を抜けて、こちらを参考にするとよいでしょう。

    1行目は、a UndefinedObjectが#doesNotUnderstand:メソッドを起動したことを表わします。括弧内のObjectは、実際にこのメソッドが定義されているクラス(メソッドホルダ)がUndefinedObjectではなく、Objectであることを表わしています。これは、ノーティファイアを起動するためのメッセージ送信です。一般にオブジェクトは自らが理解できないメッセージを受け取ると自身に改めて「doesNotUnderstand: …」というメッセージを送信する決まりになっています。なお、これに似た機構はCocoaでも採用されています。

    本題の2行目はいったん飛ばして、参考のため、4行目と3行目についても簡単にコメントしておきましょう。do it (cmd-D)という操作によって選択文字列は、エディタなどのGUI関連オブジェクトを介して、コンパイラに渡されます。4行目のa Compilerに対するメッセージ送信がこれに当たります。このコンパイルの結果、選択文字列はバイトコードの関数(つまりメソッド)になるのですが、残念(?)ながらSmalltalkの世界ではクラスに属さない関数(つまりメソッド)の存在を許していません。そこでコンパイラはとりあえず、その文脈で擬変数selfに束縛されているオブジェクト(たいていはnil)のクラス(nilならUndefinedObject)に一時的に#DoItという名前のメソッドとして登録することで、その場をしのぎます。

    3行目は、#DoItメソッドを登録したUndefinedObjectのインスタンスで擬変数selfに束縛されているnilに、改めて「DoIt」というメッセージを送信したことを表わします。この評価の後、#DoItメソッドは自動的に削除されます。do itやprint itなどのGUIを介した式の評価はあまりに手軽なので、一見、コードを直接インタープレットしているように思えるのですが、実際には、メソッドの定義とその起動のときと、まったく同じ手順(コンパイル、クラスへの登録、クラスに属するインスタンスへのメッセージ送信)を踏んでいることは、とても興味深いことですね。

    さて、問題の2行目に戻ります。2行目は字面通り、そして当初の予想通り、a BankAccountに「deposit: 100」が送信されたことを表わしています。このことから、nilが自身に「doesNotUnderstand: …」というメッセージを送るはめになったのは、このコンテキストが原因であることを改めて確認できます。BankAccount >> #deposit:の定義は、

    deposit: aNumber
    self balance: self balance + aNumber

    でしたね。今回の“騒ぎ”は、ここで送られる「+ aNumber」がnilに送られたためであることが総合的に判断できると思います。ではなぜ、nilに送られてしまったのか。答えは簡単で、self balanceがnilを返したからです。アクセッサ「#balance」の定義は、

    balance
    ^ balance

    ですから、同名のインスタンス変数「balance」に束縛されているオブジェクトを返すだけで、他にはなにもしていません。つまり、balanceにnilが束縛されているのが“騒ぎ”の真相ということになります。もう、すでに忘れておられる方もあるかもしれませんが第15回で触れたとおり、Smalltalkでは、未定義の変数には未定義値(undefined object)、すなわちクラスUndefinedObjectの唯一のインスタンスであるnilが束縛される決まりになっています。そして、nilは「+ 100」というメッセージを知らないので、自らに「doesNotUnderstand: …」を送信し、ノーティファイアを起動した、というわけです。

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

    小池邦人の「Carbon API 徒然草」(2004/11/05)

    カタログウィンドウのイベントハンドラ

    今回は、newCatalogWindow()で使われているsetupCatalogWindow()と、その関連ルーチンを調べてみます。メインウィンドウ(CatalogWindow)に実装するイベントハンドラの解説が中心となります。
    まずは、再度setupCatalogWindow()を提示してみましょう。

    void setupCatalogWindow( WindowRef window )
    {
        setupCatalogWindowEvent( window ); // イベントハンドラルーチンの実装
        setupDataBrowser( window );        // DataBrowserコントロールの初期化
    }
    


    このシンプルなルーチンの役割は、CatalogWindowの初期化を行うことです。
    実際の処理内容は「ウィンドウへのイベントハンドラルーチンの実装」と「DataBrowserコントロールの初期化」で、setupCatalogWindowEvent()が前者を、setupDataBrowser()が後者を担当しています。今回は、この2つのルーチンのうちsetupCatalogWindowEvent()についてのみ解説を行います。

    void setupCatalogWindowEvent( WindowRef window )
    {
        EventTypeSpec    list[]={
                                  { kEventClassCommand, kEventCommandProcess },
                                  { kEventClassCommand, kEventCommandUpdateStatus },
                                  { kEventClassWindow, kEventWindowClose },
                                  { kEventClassKeyboard, kEventRawKeyDown }
                                };
    
        InstallWindowEventHandler( window,myCatalogWindowEventHandler,
                                         GetEventTypeCount(list),list,window,NULL );
    }

    ここでは、4種類のイベントに対応できるようにEventTypeSpecリストが作成されています。kEventCommandProcessは、メニューアイテムやウィンドウに配置されているボタン(Control)のコマンドIDを受け取るためです。また、kEventCommandUpdateStatusは、メンテナンスが必要なメニュー(状況によりアイテムの利用可、不可を切り替える)のMenuRefを受け取り、それをメンテナンスルーチンへ渡すために使います。この2つのイベントはkEventClassCommandに属しています。ここまでの2つは、以前解説したアバウトダイアログのイベントハンドラとまったく同じです。

    続くkEventWindowCloseは、ウィンドウへの「閉じなさい!」という指令を受け取るために用いられます。ファイルメニューから「閉じる」が選択された時や、ウィンドウのクローズドボックスがクリックされた時に送られて来ます。最後のkEventRawKeyDownは、キーボードのキーが押されたタイミングで何かを実行したい時に使います。イベントからはキーボード・キーのASCIIコード、物理コード、特殊キーON/OFF状況などの情報を得ることが可能です。kEventWindowCloseはkEventClassWindowに属し、kEventRawKeyDownはkEventClassKeyboardに属しています。詳しいイベントの挙動についてはCarbonEvent.hを参照してください。

    イベントハンドラをウィンドウへ実装するのには、InstallWindowEventHandler()を利用します。また、この時にuserDataとして対応するウィンドウのWindowRefを渡しておきます。これにより、処理対象となるウィンドウをハンドラルーチン側で簡単に認識することが可能となります。以下が、メインウィンドウに実装されたイベントハンドラルーチンのmyCatalogWindowEventHandler()です。

    pascal OSStatus myCatalogWindowEventHandler( EventHandlerCallRef myHandler,
                                                    EventRef event,void *userData )
    {
        OSStatus        ret=eventNotHandledErr;
        unsigned long   ekind;
        WindowRef       wptr;
        long            cls;
        HICommand       cmd;
        char            asc;
    
        cls=GetEventClass( event );   // イベントのクラス名を得る
        ekind=GetEventKind( event );  // イベントの種類を得る
        wptr=(WindowRef)userData;     // 処理対象ウィンドウのWindowRefを得る
        if( cls==kEventClassCommand ) // Carbon Eventのクラスはコマンド
        {
            switch( ekind )  // イベントの種類で分岐
            {
                case kEventCommandProcess: // コマンドIDが届く
    
                    GetEventParameter( event,kEventParamDirectObject,typeHICommand,
                                                 NULL,sizeof(HICommand),NULL,&cmd );
    
                    switch( cmd.commandID ) // コマンドの種類で分岐
                    {
                        case 'fold': // 「フォルダから...」ボタン
    
                            importImageFolder( wptr ); // フォルダ内ファイル登録処理
                            ret=noErr;
                            break;
    
                        case 'file': // 「ファイルから...」ボタン
    
                            importImageFile( wptr ); // ファイル登録処理
                            ret=noErr;
                            break;
    
                        case 'save': // ファイルメニューの「保存...」アイテム
    
                            saveCatalogFile( wptr ); // ドキュメント保存処理
                            ret=noErr;
                            break;
    
                        case 'laun': // 「起動」ボタン
    
                            openSelectedImageFile( wptr,1 ); // ファイル起動処理
                            ret=noErr;
                            break;
    
                        case 'view': // 「表示」ボタン
    
                            openSelectedImageFile( wptr,0 ); // ファイル表示処理
                            ret=noErr;
                            break;
    
                        case 'dele': // 「削除...」ボタンと
                                     // 編集メニューの「削除...」アイテム
    
                            deleteSelectedImageFile( wptr ); // ファイル削除処理
                            ret=noErr;
                            break;
    
                        case 'sall': // 編集メニューの「すべて選択」アイテム
    
                            selectAllDataBrowser( wptr,kDataBrowserItemsAdd );
                            break;   // ファイル一覧すべてを選択する
    
                        case 'call': // 編集メニューの「選択を解除」アイテム
    
                            selectAllDataBrowser( wptr,kDataBrowserItemsRemove );
                            break;   // ファイル一覧の選択を解除する
                    }
                    break;
    
                case kEventCommandUpdateStatus: // メニューのメンテナンス要求が発生
    
                    GetEventParameter( event,kEventParamDirectObject,typeHICommand,
                                                NULL,sizeof(HICommand),NULL,&cmd );
                                    // 選択されたメニューのMenuRefを得る
                    ret=mainteCatalogWindowMenu( wptr,cmd.menu.menuRef );
                    break; // メインウィンドウ表示でのメニューのメンテナンス実行
            }
        }
        else if( cls==kEventClassWindow ) // Carbon Eventのクラスはウィンドウ
        {
            GetEventParameter( event,kEventParamDirectObject,typeWindowRef,NULL,
                                                     sizeof(WindowRef),NULL,&wptr );
                              // イベントが発生したウィンドウのWindowRfwを得る
    
            SetPortWindowPort( wptr ); // カレントポートに設定
            switch( ekind ) // イベントの種類で分岐
            {
                case kEventWindowClose: // ファイルメニューの「閉じる」アイテムか
                                        // クローズドボックスがクリックされた場合
    
                    closeCatalogWindow( wptr,0 ); // メインウィンドウを閉じる処理
                    ret=noErr;
                    break;
            }
        }
        else if( cls==kEventClassKeyboard )// Carbon Eventのクラスはキーボード
        {
            switch( ekind ) // イベントの種類で分岐
            {
                case kEventRawKeyDown: // キーボードのキーが押された場合
    
                    GetEventParameter( event,kEventParamKeyMacCharCodes,typeChar,
                                                     NULL,sizeof(char),NULL,&asc );
                                      // イベントからキーコードを得る
                    if( asc==0x8 )    // Deleteキーが押された(キーコード=0x8)
                    {
                        deleteSelectedImageFile( wptr ); //  選択ファイルを削除
                        ret=noErr;
                    }
                    break;
            }
        }
        return( ret );
    }
    


    注目すべき点は、メニューアイテムとボタンに同じコマンドID(4バイト識別子)を割り振っておけば、どちらのイベントも同じ分岐位置へ到達すると言うことです。たとえば、コマンドID=’dele’は、編集メニューの「削除…」とウィンドウの「削除…」ボタンの両方に設定されており、どちらを操作しても同じ処理が実行されます。また、コマンドID=’clos’のボタンやメニューアイテムが操作された場合には、ウィンドウのクローズドボックスがクリックされた時と同じように、kEventClassWindowのkEventWindowCloseへとイベントが送られて来ます。こうした仕組みは、ウィンドウのStandard Event Handler側でコントロールされています。

    注意する点は、ウィンドウに配置されたデータブラウザ(DataBrowser Control)にもStandard Event Handlerが実装されており、データブラウザがフォーカス(マウスクリック後に青枠で囲まれている状態)されている時には、編集メニューの特定のコマンドID(取り消し、カット、コピー、ペースト、削除、すべて選択など)を受けて、内部処理を実行するようになっていることです。こうした仕組みは、データブラウザだけではなくテキスト入力カラムなどにも備わっています。例えば、’sall’(すべて選択)は、メインウィンドウのハンドラ内で処理をしていますが、本当はアプリ側で何も行う必要はありません。ただし、データブラウザがフォーカスされていない時でも処理を実行したい場合があるわけで(今回がそう)、そうした時にはウィンドウ側のハンドラで、このコマンドIDに対応しておく必要があります。

    もうひとつの注意点は、コントロール側の内部処理が自分のアプリに合わない時には対処が必要だということです。加えて、この内部処理はMac OS Xの古いバージョンだと機能しない場合があります。このサンプルアプリを作成した当時には、データブラウザ側にはStandard Event Handlerが実装されておらず、「削除…」のコマンドIDは’dele’の代わりに’clea’(クリア)だったのですが、何の問題も生じませんでした。ところが、最新のMac OS X 10.3では、データブラウザ側がコマンドIDの’clea’や’sall’を先んじて処理してしまい、ウィンドウまでイベントが送られて来ません(コントロールがフォーカスされている場合)。そこで、最近になって’clea’を’dele’に変更して処理がちゃん実行されるように改良したわけです。こうした小手先の操作ではなく問題を完全に解決したい場合には、データブラウザにもオリジナルのイベントハンドラを実装してイベントの流れを詳細にコントロールする必要があります。

    次回は、setupCatalogWindow()で呼ばれているもう片方のルーチン、setupDataBrowser()とその関連ルーチンへと話を進めます。メインウィンドウにはファイル一覧を表示するためにデータブラウザが配置されていますが、それの初期化作業について解説します。

    つづく

    「Behind the WebObjects」  第31回  田畑 英和

     前々回から解説していますWOUnitTestフレームワークの3回目です。これまでセットアップからテストケースの作成方法までを解説しましたが、今回はフレームワークが提供しているテストケース作成用クラス”WOUTTestCase”の紹介をおこないます。

    WOUTTestCaseの概要

     WOUnitTestフレームワークを用いてテストケース用のクラスを作成するには、フレームワークが提供する”WOUTTestCase”を親クラスとしたクラスの作成をおこないます。また”WOUTTestCase”はJUnitが提供するクラス”TestCase”のサブクラスとして実装されています。例えば”MyTestCase”という名前のテストケースクラスを作成したときには次のような継承関係になります。

    “TestCase” <- "WOUTTestCase" <- "MyTestCase"

     前回は処理結果を評価するメソッドとしてassertTrueやassertFalseを紹介しましたが、これらのメソッドはJUnitの"TestCase"が提供するメソッドです。
     "TestCase"のサブクラス"WOUTTestCase"には、EOのテストを支援するメソッドが用意されていますので、具体的にどのようなメソッドが提供されているかを紹介していきます。

    Validationのテスト

     EOCustomObjectクラスにはEOValidationインターフェースで定義されているEOの正当性検証用メソッドが実装されています。その1つvalidateForSave()はEOをデータベースに保存するときにデータの正当性を検証するためのメソッドです。このメソッドをオーバーライドすることにより独自の検証ロジックを組み込むことができます。”WOUTTestCase”には、次のようなデータ保存時の検証ロジックのテスト用メソッドが用意されています。

    public static void assertValidForSave(EOValidation validationObject)
    public static void assertInvalidForSave(EOValidation validationObject)

     assertValidForSaveはEOがデータベースに*保存できる*状態であることのテスト、assertInvalidForSaveはEOがデータベースに*保存できない*状態であることのテストをおこないます。
     フレームワークには以下のようなサンプルが用意されています。このサンプルでは、customer.foo()を実行した状態ではまだcustomerをデータベースに保存できる状態ではなく、customer.bar()を実行した状態で保存ができることをテストしています。

         public void testCustomerValidates() {
             Customer customer = new Customer();
             editingContext().insertObject(customer);
             customer.foo();
             assertInvalidForSave(customer);
             customer.bar();
             assertValidForSave(customer);
         }

     ちなみにこのサンプルでは、EOを新規に作成してValidationのテストをおこなっているだけで、実際にデータベースへの保存はおこなっていません。このままではEOが未保存のまま”WOUTTestCase”が提供するeditingContext上に残ってしまいますが、WOUTTestCase.javaに実装されているtearDown()内でediting Contextをrevertし、未保存のEOを削除しています。
     tearDown()は各テスト用メソッドの実行後に毎回自動的に呼び出されますので、このサンプルのようなコードを実行しても、次のテスト用メソッドが呼び出された時点でeditingContextはクリアされており、未保存のEOが影響をおよぼす心配はありません。

    データベースの後始末

     では次にデータベースへの保存をおこなった場合の便利な機能を紹介します。テストケース上で新規作成したEOをデータベースに保存すると、当然データがどんどんたまっていってしまうことになります。別途データベースの初期化用スクリプトでも用意しておけばよいのですが、”WOUTTestCase”にはテスト中にデータベースに追加したデータを自動的に削除してくれる便利な機能があります。この機能を利用するには、データベースに追加するEOをあらかじめ次のメソッドで登録しておきます。

         protected void registerPersistentRootObjectForDeletion(
                                     EOEnterpriseObject anEnterpriseObject)
    


     すると、WOUTTestCase.javaのtearDown()でこのメソッドを用いて登録しておいたEOをデータベースから削除してくれます。フレームワークのサンプルに以下のようなコードがあります。このテストコードでは、実行中に実際にデータベースへデータの追加がおこなわれますが、テスト実行後に追加したデータがデータベース上から自動的に削除されます。ですので、データを書き込むテストをおこなった場合でも、テスト後にデータベースを別途初期化する手間が省けます。

         public void testCustomerSaves() {
             Customer customer = new Customer();
             editingContext().insertObject(customer);
             registerPersistentRootObjectForDeletion(customer);
             customer.foo();
             saveChanges(false);
             customer.bar();
             saveChanges(true);
         }
    


     なお、このサンプルコードではデータ保存に次のメソッドを用いていますが、このメソッドはWOUTTestCase.javaで実装されているメソッドです。
     このメソッドでは”WOUTTestCase”が管理するeditingContextに対してデータベースへの保存処理を実行します。

         protected void saveChanges(boolean assumeSuccess)

     boolean型の引数ですが、このメソッドでは保存処理に対するテストもおこなえるようになっています。この保存処理が成功するようなケースではtrueを、保存処理が失敗するようなケースではfalseを指定してください。

    まとめ

     WOUnitTestフレームワークの機能をすべて紹介できたわけではありませんが、JUnitを拡張してEOのテストに便利な機能が提供されていることがお分かりいただけましたでしょうか。プロジェクトのビルド時に自動的にテストを実行するようなことも考えられますので、日常の開発に役立てていただければと思います。

    さて、まもなく湘南ミーティングですね。
    参加者の皆様、初台&湘南でお会いしましょう!!

    ニュース・解説

    今週の解説担当:新居雅行

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃Mac OS X 10.3.6のアップデートが公開
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    Mac OS XおよびMac OS X ServerがVer.10.3.6へアップデートした。大幅な変更は少ないようだが、さまざまな点で小さいながらも変化はある。まず、Sambaのバージョンが3.0.5にアップデートされている。AFPも含めて、ファイル共有機能は安定性も向上させている。ディレクトリサービス関連も更新されており、Active Directoryのプラグインの更新や、ネットワークアカウントでのログインができない問題も修正が加えられている。Safariをはじめとして、アプリケーションに対する変更も行われている。SafariはWebアクセスで60秒経過するとタイムアウトになっていたが、無制限にレスポンスを待つようになった。また、スクリーンセーバでパスワード設定しているときに画面が真っ暗のままになってしまう点も解消されている。
    同時に、オープンソース部分のDarwinもVer.7.6がリリースされており、Ver.10.3.6に対応したものが公開されている。

    Mac OS X 10.3.6 Update (Delta) について
    http://docs.info.apple.com/article.html?artnum=300080-ja
    About the Mac OS X Server 10.3.6 Update
    http://docs.info.apple.com/article.html?artnum=300100
    Darwin 7.6
    http://www.opensource.apple.com/darwinsource/10.3.6/

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃アプリケーションでメールを送信機能を付ける
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    アプリケーションがメールを送信する機能ではなく、Webサイトでよく見られるような、mailtoプロトコルのリンクのような機能をアプリケーションで実現する方法が解説されている。つまり、クリックなどをすると、メールアプリケーションが起動し、そのメールで新規メールを作成するといった状態を実現する方法である。NSWorkspaceを使った機能なので、掲載されているプログラム自体もシンプルであるが、openURLメソッドで、mailtoプロトコルをURLとして与えればいいということがポイントになる。

    Technical Q&A: Sending an Email
    http://developer.apple.com/qa/qa2004/qa1084.html

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃Finderでのファイル名ソートと同一機能を実現
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    Finderではファイル名順に並べたとき、大文字小文字の区別をしないなどの処理が行われるが、システム機能としてはFinderの基準でテキスト比較する直接的なAPIは用意されていない。そこで、アプリケーションからFinderの基準で並べ替えを行う機能を組み込む方法がTechnical Q&Aで解説されている。
    UCCompareTextDefaultというAPIを利用した比較関数を作成し、配列をその関数を利用して並べ替えるというソースコードのサンプルが掲載されている。

    Technical Q&A: Sorting Like the Finder
    http://developer.apple.com/qa/qa2004/qa1159.html

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

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

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

    2004-11-02

    目次

    • “関西オープンソース2004”レポート(前編)村上幸雄★MOSA会員専用★
    • SqueakではじめるSmalltalk入門   第17回  鷲見 正人
    • 藤本裕之のプログラミング夜話 #56
    • 高橋真人の「プログラミング指南」  第55回
    • ニュース・解説
    MOSA会員専用記事

    “関西オープンソース2004”レポート(前編)

     ビッツ有限会社 村上幸雄

     開催場所:大阪産業創造館
     日  時:2004年10月22日(金)〜23日(土)
    http://k-of.jp/

     こんにちは。この度は新居さんの紹介で、関西オープンソース2004のレポートを書くことになりました村上です。
     私はオープンメール環境(OME)という、MacOS Xで利用できる、オープンソースのメールソフトのコミュニティに参加しているのですが、このOMEが昨年に続き、今年も関西オープンソース2004に参加することになり、私もこのイベントに参加しました。

    関西オープンソース2004は今年で3回目を迎えたイベントで、昨年までは関西オープンソース+フリーウェアという名称でした。また、今年は同時に関西コミュニティ大決戦とBSD Conference Japan 2004というイベントも開催されました。ただし、BSD Conference Japan 2004は23日のみの開催で、参加費が必要という事でしたので、会場の建物は共有していますが、まったくの別イベントということになります。

    まず始めにあまりオープンソースについてご存じない方のことを考えまして、オープンソースについて、少し説明させていただきます。
     オープンソースに似た用語として、フリーソフトウェアという言葉がありますが、これはソフトウェアの利用・配布とソースコードの閲覧・修正・公開の自由が一定の条件で与えられているというもので、社会運動としての側面があります。また、ユーザーと開発者の距離が近い傾向があるのも特徴の一つです。これに対してオープンソースは、ソースコードが公開されているという点はフリーソフトウェアと同じですが、その他の点については必ずしも自由という訳ではありません。例えば、MySQLのように商用のオープンソースソフトウェアというのも存在します。
     このような違いから、フリーソフトウェアを支持する人々とオープンソースを支持する人々は必ずしも一致するという訳ではありません。

    それでは、関西オープンソース2004についてレポートさせていただきます。ただし、関西オープンソース2004では複数の会場で複数のプログラムが同時に進行していた関係から、私が参加したプログラムのみの紹介となってしまうことをご了承ください。

    基調講演

     基調講演は二本ありまして、一本目は産業技術総合研究所 主任研究員の田代秀一氏の「経済産業省のOSS支援」で、経済産業省が国内で取り組んでいるオープンソースソフトウェア(OSS)基盤整備事業やデスクトップ導入実験の紹介と、国際活動のアジアOSSシンポジウムや日中韓OSS推進フォーラムの説明、これに連動する形で設立された日本OSS推進フォーラムの説明です。
     私が田代氏の説明で印象に残ったことをあげてみますと、以下のとおりです。

     ・ヨーロッバでは単一のソフトウェアがインフラの大部分を占めているのは問題という認識があり、OSSの導入はこの問題への対応の一つ。

     ・日本では、サーバ側でのOSSの利用は進んでいるが、クライアント側のOSでは使用されていない。

     ・著作権をソフトウェアに適用してしまうと、例えば文章と異なりバイナリ形式のソフトウェアは内部を知ることが出来ないので、開発者の利益を守ることは出来るが、特許の場合と異なり、内部情報が公開されない為、技術発展に貢献することができない。

     基調講演の二本目は、京都市総合企画局情報化推進室情報政策課 情報企画担当課長の豊田博一氏の「京都市の高度情報化施策について」で、京都市のITへの取り組み「e-京都21」の説明です。
     国のITへの取り組みでは、具体的でない、かつ、実現が難しい目標を設定することがありますが、e-京都21では、地方自治体では財源が乏しいという事情もあって、実現可能な具体的な目標(年限、数値等)を設定し、毎年の見直しを行う為に、PDCAのマネジメント・サイクル(Plan→Do→Check→Action→Doに戻る)で運営していると説明されていました。

    講演「社会運動としてのソフトウェア改革–開発と利用、その自由」

     講演者の自由ソフトウェア活動家 g新部裕氏は、フリーソフトウェアの世界では著名な方のようですが、残念ながら私は知りませんでした。その為、前知識なしで講演を聴かせていただいたのですが、聴いてみて驚きました。大変面白い内容です。実際、公演中は会場から賛同の声や、笑い声、意見が飛び交っていました。
     講演の内容は多種多様で、短くまとめるのは難しいので、私が面白いと感じたことをあげさせていただきます。
     g新部氏は、五体投地巡礼と莫高窟というプロジェクトを考えられています。五体投地巡礼は、プログラマは忙しいといってドキュメントを書かない場合が多いですが、しっかりとBlogは書いていることがあります。このような現実から、Blogのようにプログラマがソースコードに対してコメントをつけることができ、かつ、検索・閲覧できるシステムを構築するという内容です。
     莫高窟は、ソースコードの改変を全て記録するいうことと、写Codeという写経と同様に過去の優れたソースコードを書き写すといった内容です。特に写Codeについては反響が多く、会場から「声に出して読みたいCode」という提案もありました。

    (後編に続く)

    執筆者プロフィール

    村上幸雄(有限会社ビッツ)
    埼玉県朝霞市でソフトハウスを営んでいます。Mac OS XからUnix、Windows、状況によっては組み込みシステムの受託開発を主な業務としています。

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

     本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。前回は、a BankAccountのインスタンス変数balanceへの外部からのアクセス手段、#balance、#balance:を定義しました。引き続き、出納機能を追加してゆきます。

    クラスBankAccountに属するインスタンス(a BankAccount)は、たとえば「deposit: 100」というメッセージを受けて、インスタンス変数balanceに、パラメータである100を加算する挙動を示すことが期待されます。depositは預金という意味です。これを素直に書き下ろすと、メソッド定義は次のようになります。

    deposit: aNumber
    balance _ balance + aNumber

     また、前回定義したアクセッサ、#balance、#balance:を使って、このように表現することも可能です。

    deposit: aNumber
    self balance: self balance + aNumber

     念のため。このメソッド本体の式(二行目)で、二項メッセージ「+ aNumber」は、単項メッセージ「balance」の送信の結果(返値の数値)に対して送信されます。また、二項メッセージ「+ aNumber」は、キーワードメッセージ「balance: …」より優先されるので、この式は、

    self balance: ((self balance) + aNumber)

    のように解釈されることは、もう大丈夫ですね。

     話を戻しましょう。この2つの書き方、つまりアクセッサを“使わない”(前者)、または“使う”(後者)には、少なくとも現時点では違いはなく、同じ挙動を示します。パフォーマンスや読み下し易さの点では前者が、再利用性では後者が有利です。どちらを使っても良いのですが、クラス内で方針を統一することが大切です。ここではこの先、クラス継承を利用した差分プログラミングの話に繋げることを念頭に置いて、後者を選択することにします。

    メソッド#deposit:を定義するにあたり、カテゴリを新設しましょう。カテゴリ名は「accounting」にします。ここまで特化されたメソッドを、どのカテゴリに分類するかについて、もはやお手本になるクラスをシステムから探すことは(不可能、あるいはまったくの無駄ではないにせよ)難しいので、カテゴリ名の付け方は、このクラス定義を初めてブラウズする人の分かりやすさに対して最低限の配慮があれば、自由にしてよいと思います。

    カテゴリを新設するには、メソッドカテゴリペイン(メッセージカテゴリペイン、プロトコルペイン、とも言う。ブラウザ上段右から2番目のペイン)の黄ボタンメニューからnew category…を選びます。

    [fig.A]メソッドカテゴリペイン、黄ボタンメニューのnew category…
    http://squab.no-ip.com:8080/mosaren/uploads/17a.png

     候補がポップアップメニューとして提示されますが、差分プログラミングをしているとき以外は、あまり役に立たないので、素直にnew…を選びます。すると、fill in the blankが現われるので「accounting」とタイプして入力し、accept(Acceptボタンのクリックか、cmd-Sをタイプ)します。acceptと同時に、メソッドカテゴリペインには新設のaccountingカテゴリが追加され、選択状態になります。同時にコードペインには、このカテゴリに属するメソッドをただちに定義可能なように、くだんのメソッド定義テンプレートが表示され、選択状態になるはずです。

    [fig.B]追加されたaccountingカテゴリ
    http://squab.no-ip.com:8080/mosaren/uploads/17b.png

     マウスポインタをコードペインに合わせ、deleteキーでメソッドテンプレートを消去したのち、#deposit:の定義(上の後者)をタイプして入力、あるいは、このメールからコピー・ペーストしてください。同じペインのシフト黄ボタンメニュー(shiftキーを押しながら黄ボタンメニュー呼び出し、あるいは、黄ボタンメニューからmore…を選択)からpretty printを選択してコードのスタイルを整え、accept(cmd-S)します。

    [fig.C]#deposit:の定義
    http://squab.no-ip.com:8080/mosaren/uploads/17c.png

     これで、a BankAccountは「deposit: …」メッセージを受け取ることができるようになります。すでに何度か利用しているa BankAccountを束縛したインスペクタの作業用ペイン(一番下のペイン)で、次の式をタイプして入力してからdo it(cmd-D)してみてください。

    self deposit: 100

    [fig.D]a BankAccount への「deposit: 100」メッセージの送信
    http://squab.no-ip.com:8080/mosaren/uploads/17d.png

     評価の結果、インスタンス変数balanceの値が100だけ増加すれば、機能は正常です。

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

    Squeak関連のお知らせ:
     このたび、オブジェクト指向界でもその名を知られる梅澤真史氏による「自由自在Squeakプログラミング」(SRC刊、ISBN:4883732037)が出版されました。日本人、しかも本格的Smalltalkプログラマによる初の書き下ろしSqueak関連書籍ということもあり、内容も充実、盛りだくさんで気合いが入っています。Squeakを通じてSmalltalkに興味を持つようになった方は、その学習に役立ててみてはいかがでしょうか。

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

     嘘ついてごめん。前回の最後で「次回はずっと散文的かつ形而上的に『好き/嫌い』と『良い/悪い』の問題について与太話を書きたい」と書いたけど、もそっと興味深いテーマが見つかったのでそっちを書きます。「好き/嫌い」と「良い/悪い」の話はまたあとで。

    過日(ほんとは昨日なんだけど、これをあなたか読んでいる日からいうと「過日」のほうがなんぼか正確だと思う。こういう細かい差異にこだわるのがプログラマ的)、都内某所のお茶の水はデジハリで行なわれた「第87回お茶の水デジコンサロン」という会合……まぁ毎回ゲストスピーカー(ノーギャラ、二次会の飲み屋で払わなくていいだけ)を頼み、さまざまなテーマのお話を聞くという勉強会みたいなもんなんだが、に出席、社団法人コンピュータソフトウェア著作権協会(ACCS)の葛山さんというヒトのお話を聞いた。

    話は大きく分けて2つ。まずはヤフオクのようなネットオークションにソフトウェアの海賊版が出品される問題に、同協会がどのように取り組んでいるか。それからもう一つはあの作者が逮捕された「Winny」に代表されるファイル交換ソフトを使った著作権侵害に関する話。
     まず前者については、オークション主宰のヤフー(株)などと話し合い対策をとって来た結果、一時のような百鬼夜行状態はなくなったものの、世に盗人のタネは尽きまじという通りで日々戦いは続いております、と。
     で、オレが考えさせられる問題だなぁと思ったのは後者の方なのね。葛山さんも「この問題についてはネットとかでいろんなヒトがいろんなことを書いていらっしゃるんですが、どうも一面的にしかものをみていないヒトが多くて」とおっしゃってたが、普通のヒトはそうだろうなと思うのだ。
     意見の一方はつまり「著作権侵害をするためのソフトを作ったんだから捕まって当然、罰せられて当然である」ってやつ。これがスライダーの左の端だとすると、右の端は「それは包丁でヒトが刺し殺されたら包丁を作るヒトを罰するぞって議論ではないか、そんな阿呆な話があるか」という意見が来る。
     いや、本音のところでは「うるさいうるさいオレが違法コピーをできなくなっちゃうぢゃないかばかやろばかやろ」って意見もかなりあるに違いないんだけど、さすがにそういうコトを公然というヒトはいないのでね(笑)。

    とにかくたいていのヒトの意見はこのスライダーのどっかにある。そりゃ包丁はあれだけどWinnyの場合、それを使って行なわれるファイル交換は九分九厘まで著作権侵害なわけだからとか、新しい技術の進歩発展にあたって既存の権利権益とバッティングが生じるのはしかたのないことではないかとか。
     ところがプログラマであるオレはそのどっちにもなんだかなぁと思ってしまうのだ。そりゃもちろん、自分の作ったソフトウェアの著作権が侵害されるのは困るのだが、同時に自分の作ったソフトウェアがなんらかの形で犯罪に使われないとも限らないわけで、ちょっと考えるだけでオレの意見はスライダーの上を右往左往しちゃうんである。
     プログラマになりたてのころだった。鉄道関係の会社の仕事で、信号制御のプログラムの一部を作ったことがある。駆け出しのオレがやらされたのは表示部分で、間違っても人命に関わるようなモノではなかったが、そういうヒトの生き死にに関わるような仕事はできるなら勘弁してもらいたいと思ったモンだ。いまだってそう思っているし、できれば犯罪を行なうようなヒトに自分のソフトが使われなければいいなぁとも思う。包丁を作っているヒトだってこれで人を刺したりはして欲しくないと思うだろう。

    うまくはいえないんだが、この件に関してスパっと割り切った明確な意見を持ってて、しかもそれが正しいんですと胸を張れるようなヒトを、すまぬがオレは信用できない気がする。そういう問題ってのが世の中にはあるんだよ。みなさんはどう思いますか?
    (2004_10_29)

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

    UNIXとしてのMac OS X

    〜Perlについて(1)〜

     こんにちは、高橋真人です。
     さて、前回までPowerBook1台でできるCGI環境の構築についてお話ししてきましたが、その中で余り触れることのできなかったPerlというスクリプト言語について少し掘り下げて見てみたいと思います。
     Perlというと、最近ではもっぱら「CGIのための言語」ととらえている人が多いのですが、Perlは決してCGIのために作られた言語ではありません。私はまだインターネットが今のように一般に使えるようになる以前からPerlに親しんでいたために、「Perl=CGI」という公式は私の頭の中にはなく、Perlというのは「テキスト処理のためのツール」なのだと思っています。
     もちろん、Perlの可能性はテキスト処理だけにとどまるものではなく、バイナリーの処理はもちろん、ネットワーク処理、システム管理などにも使われますし、デーモンプロセスすら書くことも可能です。
     Perlという言語は、UNIXという文化の中で生まれてきたこともあって、C言語を多分に意識した仕様になっています。ある意味「Cで書くと面倒なことを簡単に」といった面持ちを持つので、私はよく他人に「将来Cをやるつもりなら、Perlに先に手を出さない方がいい」とアドバイスします。
     実際、Perlをある程度使いこなせるようになってからCを学び始めると皆、Cの「融通の利かなさ」に一様に驚くようですが、逆に言えばそれだけPerlは「かゆいところに手の届く」言語だということでもあるわけです。
     ご存知の方も多いと思いますが、Perlがこの分野で大きな成功を収めたこともあって、このテキスト処理系のスクリプト言語という分野は非常に活発です。オブジェクト指向機能を加えたPythonや日本人が作ったことでも有名なRubyなど、いずれも使いやすく強力なこれらのツールは、互いに影響を与え合いながら発展・進化し続けています。
     MacとWindows、CocoaとCarbon、XcodeとCodeWarriorなどなど、世の多くの人は物事を対立軸でとらえ、とかく自分をどちらかの「派」に置きたがる傾向があるようですが、これらのスクリプト言語を作成した作者たちは興味深いことに皆さん人格者で、ユーザーほどには他の言語を忌み嫌ったりしていないようです。
     Perlの作者のLarry Wall氏は、文章も巧みで面白いと言われています(残念ながら私はまだ彼の言葉を原文で味わえるほどの英語力がありません)が、寛容さもなかなかのもので、Perlのスローガンとして有名な「TMTOWTDI」(There’s More Than One Way To Do It.)という言葉の意味する「やり方はいくつもある」という言葉は、Perlを極めて多彩な言語にすることに一役買っているように思います。
     Perlは言語仕様も簡素というには余りにも多機能ですし、他の言語の持たない多くの特徴を持つことから、自在に使いこなせるようになるためにはそれなりの期間を要します。しかし、初心者が自分の覚えたての機能だけで書いたたどたどしいコードも、Perlのベテランユーザーが持てるワザを駆使して書いた、一見「何が書いてあるのか、分からない。一体どうしてこれだけのコードでこんなことができるの?!」というようなコードも、どちらもPerlのコードとしては「正しい」のです。
     世にはたくさんのPerlの本があります。Perlの解説をしているWebサイトもかなりの数に上るでしょう。ですから、それらの本を読めば必要なことは十分に集められると言えばそうなのかもしれませんが、そこはそれ、TMTOWTDIの精神で私なりのPerl紹介をしてみたいと思っています。

    ニュース・解説

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

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

    【開発環境】

    新居さんも前号で紹介されていましたが、Apple社から「Tiger Early Start Kit for Developers」なるものが発表されました。Mac OS X 10.4(Tiger)に関する開発者向けドキュメントやTigerプレビュー版(WWDCで配布された物より新しいバージョンだと思われる…多分)がパッケージされた商品(?)のようです。最初にこの発表を見た時「なんだ!これを購入しないとTigerの最新プレビュー版は手に入らないのか?」と慌ててしまいましたが、内容を読み返してみると、どうやらADC Selectメンバであれば自動的に送られて来るようです。つまり「ADC Selectメンバへの勧誘プロモーショングッズ」と言うわけですね(笑)。何だかちょっとセコイような気もしますが、Macintoshと深く関わっている開発者ならば、年間5万円程度の経費で色々と特典が得られますので、この機会にADC Selectメンバへ昇格しておくのも悪くないと思います(筆者経験談)。

    http://developer.apple.com/macosx/tiger/tigerkit.html?headlines

    同時に、全米6箇所で「Mac OS X Tiger Tech Talk」(無料)という催しも開催されるようです。Tigerに関する開発者向けのデモやプレゼンテーションだけでなく、ハンズオンやフィードバックも行われるようです。こうした催しは日本国内でもぜひ開催していだだきたいものですね…。

    http://developer.apple.com/events/techtalks/index.html

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

    前回から10月29日の期間中、Apple社のDocumentationサイトには新規ドキュメントが2つ登録されました。新型iBook G4と、新しくラインアップに加えられた1.8GHzシングルプロセッサのPowerMac G5に関する仕様ドキュメントです。デベロッパ向け読み物としての解説も2つ登録されています。「Mac OS X v10.4 Tiger: Developer Overview」の方では、Tiger(Mac OS X v10.4 )の新機能を簡潔に解説しています。このドキュメントの内容については、前号の新居さんの記事も参考にしてください。

    「Power Mac G5 — Single Processor Developer Note」(PDFあり)
    「iBook Developer Note」(PDFあり)

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

    「NeuroLens and Mac OS X: Modernizing Brain Imaging」」(読み物)

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

    「Mac OS X v10.4 Tiger: Developer Overview」(読み物)

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

    前回から10月29日の期間中、新規のテクニカルノートはひとつも登録されませんでしたが、新しいテクニカルQ&Aは6つ登録されました。QA1160とQA1340は、どちらもシステムのスリープ状態に関連する内容です。開発アプリケーションがスリープ状態に入ることにより何らかの影響を受けるようであれば、これらのQ&Aは問題解決のために大変参考になります。「Sorting Like the Finder」には、UCCompareTextDefault () APIを使い文字列をソートする手法がサンプルソース付きで紹介されています。「Private HITheme APIs in Mac OS X 10.2 should not be called」には、Mac OS X 10.2では実装されていないHITheme APIの一覧が明記されています。

    QA1377「Private HITheme APIs in Mac OS X 10.2 should not be called」
    QA1361「Detecting the Debugger」
    QA1159「Sorting Like the Finder」
    QA1383「Enabling X11 Forwarding 」
    QA1340「Registering for sleep notifications」
    QA1160「Preventing sleep 」

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

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

    前回から10月29日の期間中、Apple社のSample Codeサイトには、新しいサンプルソースコードが4つ登録されました。「ScrollAndZoom」は、久しぶりに登録されたQuartz 2D(CoreGraphics)関連のサンプルソースコードです。カレントCGContextのトランスフォーメーション・マトリックスをCGContextScaleCTM()やCGContextTranslateCTM() APIを使い操作することで、描画内容をダイナミックに更新することができるサンプルアプリケーションが紹介されています。

    「SimpleReach」(Network関連)
    「SimpleDial」(Network関連)
    「ScrollAndZoom」(Quartz 2D関連)
    「QDCocoaComponent」(Cocoa関連)

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

    【デベロップメント SDK】

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

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

    その代わり、デベロッパー向けツールとしてCHUD(Computer Hardware Understanding Development Tools)4.0.0(正式版)の配布が開始されました。すでにCHUDをインストールしている方には、CHUD Updaterが最新版をダウンロードするためのダイアログを表示して教えてくれるはずです。

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

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

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