MOSA Multi-OS Software Artists

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

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

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

MOSADenバックナンバー 2007年7月発行分

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

    2007-07-31

    目次

    • 「りんご味Ruby」       第8回  藤本 尚邦
    • 藤本裕之のプログラミング夜話   #119
    • 高橋真人の「プログラミング指南」  第117回
    • 書籍紹介            たのしいCocoaプログラミング

    りんご味Ruby   第8回  藤本 尚邦

    先日、最近Ruby on Railsを始めたというCocoaプログラマの方と話していたところ、Rubyのメソッド呼出し記法はややこしいと愚痴を聞かされてしまいました。たしかにバリエーションが多くて、Rubyプログラミングを始めたばかりの人には混乱の元になるかもしれません。

    では、Rubyプログラミングに習熟した人にとって、このバリーエションの多さはどんな意味を持っているのでしょうか? 多くのRubyプログラマは、場面に応じて、メソッド呼出し記法を上手に使い分け、プログラムの可読性を高めています。ということで今回は、Rubyにおけるメソッド呼出しについて解説します。

    ■ メソッド呼出しのプロセス

    まず、Rubyにおけるメソッド呼出しのプロセスを明らかにしておきましょう。基本的には、実際の動作も含めてObjective-Cの場合と良く似ています。メソッド呼出しの対象となるレシーバ(受け手)オブジェクトの立場から見ると、おおよそ以下のようなプロセスになります。

    ・レシーバがメッセージ(メソッド名と実引数)を受信
    ・対応するメソッドを検索
     ・見つかった    => メソッド実行
     ・見つからない  => 自身にmethod_missingメッセージを送信
    ・値を返す

    method_missingは、デフォルトでは「メソッドが見つからなかった」という例外を発生させます。自分で再定義することにより、柔軟なプログラミングが可能です。例えば、拙作のRubyCocoaでは、method_missingに落ちてきたメッセージを関連するObjective-Cオブジェクトに送信します。

    ■ メソッド呼出しの記法 — 括弧付き実引数リスト

    メソッド呼出しの基本的な構文は以下のようになります。Java,C++あたりの言語に親しんでいる方にはおなじみのものでしょう。

     レシーバ.メソッド名()
     レシーバ.メソッド名(実引数リスト)

    レシーバとメソッド名の間はドット「.」で区切ります。ドットの前後にはスペースを置くことができます。実引数リストは、実引数をカンマ「,」で区切ります。カンマの前後にもスペースを置くことができます。具体例を上げておきましょう。以下は文字列オブジェクト(文字列リテラル)をレシーバとした例です。

     "hello,world".length()         # => 11
     "hello,world".gsub('o', 'O')   # => "hellO,wOrld"

    ■ メソッド呼出しの記法 — 括弧の省略

    実引数リストを囲むための括弧は省略できます。実引数が存在する場合には、メソッド名と実引数リストの間にスペースを置きます。一般的に、実引数がないメソッド呼出しでは括弧を省略するのがRuby流と言えるでしょう。

     レシーバ.メソッド名
     レシーバ.メソッド名 実引数リスト

    先ほどの例で括弧を省略すると以下のようになります。

     "hello,world".length           # => 11
     "hello,world".gsub 'o', 'O'    # => "hellO,wOrld"
    

    実引数がある場合は、基本的には括弧を付けた方が見やすいかもしれません。このあたりは好みに左右されるところです。私の場合は、返ってきた値を使うメソッド呼出しでは、括弧で引数を囲みます。そうでない場合には、括弧を省略したりつけたり、見た目に応じて臨機応変に書いています。

    Rubyの効用としてときどき例に上げられるDSL(Domain Specific Language)では、括弧の省略が効果的に用いられます。

    [参考] 以下のURLでは、「リファクタリング」の著者でもあるマーチン・ファウラー氏がDSLとRubyの関係について書いています。興味のある方はご覧ください。

    ■ メソッド呼出しの記法 — レシーバの省略

    実際のところ、本連載でこれまでに書いたRubyプログラムのかなりの部分ではレシーバが省略されていました。

     メソッド名()
     メソッド名(実引数リスト)
     メソッド名
     メソッド名 実引数リスト

    具体例を上げましょう。

     require 'rss/2.0'
     open('/etc/hosts')
     puts
    


    などです。レシーバを省略してメソッドが呼び出された場合、self という名前で参照できるオブジェクトがレシーバとなっています。Rubyのプログラムが評価(実行)されているときには、常に何かしらのオブジェクトがselfになっています。インタプリタが動き始めた直後の最上位(TOPLEVEL)では、mainと呼ばれるオブジェクトがselfになっています。今回詳しい説明はできませんが、省略されている場合、実はselfがレシーバなのだ、ということだけ覚えておいてください。

    ■ (補足) 行末の意味

    JavaやCを始めとするメジャーな言語の多くは、セミコロン「;」を文の区切りとしています。同じく、Rubyでもセミコロンは文式(Rubyの文は式でもあります)の区切りを意味します。しかし、実際にRubyのプログラムを見ると「;」はあまり使われていないことにお気づきかもしれません。なぜでしょうか? それは、Rubyでは行末が文式のおわりである場合に「;」を省略できるからです。

    メソッド呼出しの記法にもどると、レシーバとメソッド名を区切るドットおよび実引数リストを区切るカンマの「後」には改行文字を置くことができます。「前」ではなく「後」だけです。これは、まさに行末のセミコロンが省略可能であることと表裏一体の関係になっています。

    以下は、NSWindowのインスタンスを生成初期化するRubyプログラムです。この場合、レシーバが「NSWindow.alloc」で、メソッド名は「objc_send」になります。両者の間のドット「.」と行末の位置関係に注目してください。

    ----------------------------------------------- 正しいプログラム ---
    NSWindow.alloc.
     objc_send(:initWithContentRect, [0,0,800,600],
                         :styleMask, NSTitledWindowMask,
                           :backing, NSBackingStoreBuffered,
                             :defer, false)
    -----------------------------------------------
    
    ----------------------------------------------- 2行目が構文エラー ---
    NSWindow.alloc
     .objc_send(:initWithContentRect, [0,0,800,600],
                          :styleMask, NSTitledWindowMask,
                            :backing, NSBackingStoreBuffered,
                              :defer, false)
    -----------------------------------------------
    


    前者では、レシーバ NSWindow.alloc に対して objc_send メッセージが呼ばれるのに対して、後者では、NSWindow.alloc で文式が途切れてしまいます。2行目は、レシーバの部分がなくて、いきなり「.」で始まるため構文エラーになります。

    次回も、引き続きメソッド呼出しについて説明する予定です。

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

     というわけでようやく,というか遂にというかここまで来たぞ。前回まででヘッダファイルにその宣言だけ行ったメソッドをさくさくとコーディングしていこう。まず最初は呼び出し側,すなわち…なんて名前にしたんだっけ? あんまり長期に渡る大河連載なので忘れちゃったよ,そうそう,MyApplication.hを開き,このオブジェクトに前回定義したプロトコルをサポートさせる。最初にプロトコルの定義を書いたヘッダーファイルをインポートする。

    #import "MyTabViewController.h"

     次にこのオブジェクトの定義にプロトコルの宣言を加える。こんな具合。

    @interface MyApplication   : NSApplication 
    {
        AboutWindowController*        aboutWindowController;
        MyTabViewController*          tabViewController;
    }
    
     NSApplication というスーパークラスの後にある<>で示された部分が,「こ
    のオブジェクトは MyTabViewOwner というプロトコルをサポートしてます」と
    いう意味である。次にプロトコルのためのメソッドの宣言。これはIBAction
    ぢゃないので(まぁIBActionの定義は「#define IBAction void」なので
    IBActionと書いてもいいんだけどさ)以下のようになる。
    
    - (void)button1:(id)sender;
    - (void)button2:(id)sender;
    - (void)button3:(id)sender;
    
     そしたら MyApplication.m を開き,-tabView:didSelectTabViewItem: の
    コードにこのオブジェクトをターゲットとして渡すシーケンスを加えて,上の
    3つのメソッドを書く。
    
    -(void)tabView:(NSTabView*)tabView didSelectTabViewItem:(NSTabViewItem*)tabViewItem {
        NSString* identifier = [tabViewItem identifier];
        if([identifier isEqualToString:@"2"]){
             if(tabViewController == nil){
                  tabViewController = [[MyTabViewController alloc]
                                      initWithWindowNibName: @"TabView"];
                  [tabViewController setTarget:self]; /* 今回追加分 */
                  [tabViewItem setView:[[tabViewController window] contentView]];
             }
        }
    }
    - (void)button1:(id)sender {
        NSLog(@"button1 pressed.");
    }
    - (void)button2:(id)sender {
        NSLog(@"button2 pressed.");
    }
    - (void)button3:(id)sender {
        NSLog(@"button3 pressed.");
    }
    
     お次は MyTabViewController.m,まずは上で呼ばれている setTarget: を
    コーディング。
    
    - (void)setTarget:(id  )target {
        _target = target;
    }
    
     そして各ボタンからのアクションをこのターゲットにリレーする。
    
    - (IBAction)button1:(id)sender{
        [_target button1:sender];
    }
    - (IBAction)button2:(id)sender{
        [_target button2:sender];
    }
    - (IBAction)button3:(id)sender{
        [_target button3:sender];
    }
    


     これでよし。ボタンを押すと MyApplication の該当のメソッドにそのアクションが飛んでくる。……これでおしまいのつもりだったが,タカハシ編集長からこれらのボタンのEnable/Disableも切り替えたいという要望があったので,次回はそれをやります。いよいよ暑くなりましたが皆さんご自愛くだされ。
                                (2007_07_26)

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

    プログラマのためのオブジェクト指向再入門(25)

    〜XcodeによるPowerPlant X入門(8)〜

     こんにちは、高橋真人です。早速続けます。
     さて前回のプログラムで、なぜウインドウがあるときにHandleClose()が呼ばれなかったのかということについて見ていきたいと思います。
     それには、前に説明しましたイベントターゲットが関係しています。前回の例では、Carbonイベントのターゲットをすべてアプリケーションにしてありました。つまり、自前でインストールしたイベントハンドラはすべてアプリケーション(MyApplicationのインスタンス)が受信したイベントのみを処理していたわけです。
     ところが、Windowが表示されてアクティブになっている場合、Carbonイベントはまずそのウインドウに送られるようになっています。
     お分かりと思いますが、この辺は、PPxに特有の話ではありません。詳しくは、

    http://developer.apple.com/documentation/Carbon/Conceptual/Carbon_Event_Manager/Concept/chapter_2_section_2.html#//apple_ref/doc/uid/TP30000989-CH202-TPXREF103

    などを読んでいただくと理解できると思います。
     簡単に解説しますと、メニューの選択によって発生したHICommandのCarbonイベントは、アプリケーションに送られる前にアクティブなウインドウに対して送られます。
     Carbonイベントの仕組みとして、最初にイベントを受け取ったウインドウが処理しなければこのイベントはアプリケーションに渡ってくるわけですが、PPx::Windowには最初からウインドウに対して送られる主だったイベントを処理するハンドラが装備されているため、kHICommandCloseのコマンドイベントは、そこで処理されて(つまりWindowを閉じた)しまいアプリケーションには渡らなかったのです。(だから、MyApplicationのHandleClose()は呼ばれなかった)

     これを確かめるために、簡単な実験をしてみましょう。
     Xcodeで新規のCarbonアプリケーションを作成してください。CでもC++でもよいですが、必ずnibファイルを使用しているステーショナリを選んで作成してみてください。
     コードは特にいじらずに、そのままビルドして走らせると新規ウインドウが開きますね? それが確認できたら一度アプリケーションを終了させ、この新規ウインドウを作成する元になっているNibファイルを開き、ウインドウのインスペクタを表示させて”Standard handler”のチェックボックスをオフにしてください。
     Nibを保存したら再度ビルドして走らせてみましょう。表示されたウインドウをいろいろいじってみてください。

     どうでしたか? メニューからCloseを選んでもウインドウが閉じないのをはじめ、ドラッグもリサイズも、ウインドウのミニマイズ(ドックにしまうこと)以外の動作はメニューにもマウスクリックにも一切反応しないはずです。
     これが、ウインドウにイベントハンドラがインストールされていない時の挙動です。
     それでは今度は同じことをPPxアプリに対してもやってみましょう。先ほどと同様にNibファイルを開いてウインドウの”Standard handler”のチェックを外してみて試してみてください。
     どうでしょう? 同じになりましたでしょうか? ならなかったと思います。”Standard handler”のチェックを外したにもかかわらず、ウインドウはちゃんとすべての動作に反応します。
     一体、どうなっているのでしょう?
     実は、PPx::WindowはNibを使わずに作成することも可能になっているため(以前、PPxがNibを使うようになったのは最初からではないとお話ししたことを思い出してください)、以下のようなコードだけで、新規にウインドウを生成することができるのです。

    PPx::Window* theWindow = new PPx::Window;
    Rect bounds = { 20, 20, 400, 400 };
    theWindow->Initialize(kDocumentWindowClass, kWindowNoAttributes, bounds, CFSTR("PPxWin"));
    


     注目してほしいのは、Initialize()の引数としてkWindowNoAttributesというのを渡していて、外部からはこのウインドウに対してハンドラをインストールするように指示してはいないことです。(一般的なCarbonの処理では、kWindowStandardHandlerAttributeをウインドウ作成の際に渡す)
     それでも、クローズボックスなどはアクティブにならないものの、ドラッグなどのマウスイベントには対応しますし、メニューからのClose命令にもちゃんと応じるようになります。
     何でそんなことが起きるかと言えば、単純な話で、PPx::Windowがウインドウの生成の際に「勝手に」kWindowStandardHandlerAttributeなどの属性指定をしてウインドウを作成しているだけのことなのです。(先ほどのNibで外したチェックボックスはこの属性をコントロールしていたわけです)
     まあ、実際のアプリを作る場合これらの標準的なイベントハンドラはあるのが普通なので、これでいいのです。「必要なことには極力ユーザーの手を煩わせない」。これが、アプリケーションフレームワークの正しい姿でしょう。
     しかしながら、アプリケーションフレームワークとしては、同時に逆のケースにも対応できなければなりません。つまり、ユーザーがその標準的なハンドラを組み込みたくない場合にその要求を満たす手段を用意することです。
     PPxにも当然その手段は用意されています。HandlerNew()の先頭に、

    PPx::Window::SetDefaultAttributes(kWindowNoAttributes);

    という一行を追加するだけでOKです。これをすることで、PPxが「勝手に」ウインドウにイベントハンドラを組み込むことを抑止できます。

     ちょっといろいろと試してしまいましたが、ようやくこれで最初の目的を達成できるようになりました。つまり、いま触れたやり方を使えば、ウインドウにkHICommandCloseを処理するハンドラもインストールされないので、イベントはアプリケーションに渡り、MyApplicationのHandleClose()が呼び出されるようになります。
     実際に試されてみれば、コンソールに、HandleClose called.と表示されるのが確かめられるでしょう。
     あれ、ちょっと待ってください。メッセージは表示されたのに、肝心のWindowを閉じる処理が行われなくありませんか?
     困ったことに、これはPPxのバグなのです。
     PPxWindow.cpを開き、Window::Close()を以下のように書き換えれば、このバグは解消されます。

    void
    Window::Close()
    {
        SysCarbonEvent    closeEvent(kEventClassWindow, kEventWindowClose);
    
        SysEventParam::Set(closeEvent, kEventParamDirectObject, GetSysWindow());   // ここを追加
    
        closeEvent.PostTo(GetSysEventTarget());
    }
    


    それから、ソース冒頭のinclude部分に一行追加してください。

    冒頭部
    #include 
    #include 
    #include 
    #include 
    #include 
    #include   // ここを追加
    
    namespace PPx {
    ....
    
    

    書籍紹介        木下 誠 著 たのしいCocoaプログラミング

     解説担当:高橋政明

    たのしいCocoaプログラミング
     木下 誠著
     株式会社ビー・エヌ・エヌ新社  ISBN978-4-86100-443-8  2,940円

     六月末に出版されたばかりのCocoaプログラミングの入門書です。著者はモサ伝でニュース解説を担当していただいていた木下さんです。書籍紹介で木下さんの著書をご紹介するのは二度目ですが木下さんのCocoaの本としては五冊目だそうです。

     Macのデスクトップアプリケーションのプログラミングがはじめての人とプログラム作りそのものが初めての人両方に向けて書かれていて、全体は五つのパートに分かれています。合計20のLessonからなり、すべてのLessonの最後のページには半ページほどの「このレッスンで学んだこと」が載っています。
     プログラムを作る作業はたくさんの(現在では膨大と言った方が正確なほど)の前提知識が必要ですが、要所ごとにこのようにまとめがあり次のレッスンへ導く書き方は読者に親切ですね。

     入門書は実際にプログラムを作るためのたくさんの情報を整理して記述しなければなりません。この点木下さんがAppleでCocoaのセミナーを担当された経験を生かしてまとめられています。開発環境のインストールにはじまり、アプリケーションやフレームワークの解説とXcodeの解説、開発手順の説明とMVCアーキテクチャとアウトレットとアクションの説明、C言語とObjective-Cの解説、Cocoaの基本的なクラスの解説、最後にエラーメッセージの対応とデバグ作業そしてアプリケーションにアイコンを付けたり日本語を表示する方法まで続きます。
     全ページ二色刷り、350ページを超えますが紙質を工夫し物理的にも軽い本に仕上がっています。ただし情報はC言語の解説も含むなど盛りだくさんで相対的にCocoaの細かなクラスの解説は必要最小限です。この点最後にさらに一歩進むための情報として「もっといろんなCocoaのクラスを使う」「いろんなフレームワークを使う」「サンプルを調べる」「Appleのサイトを参考にする」が解説付きで載っています。

     これからCocoaをはじめるCarbonプログラマにも「最新環境に対応した入門書」のひとつとしておすすめです。

     プログラミングはやり始めるまでが大変ですが、知識が広がりその知識をプログラミングに実際に活かすことは「たのしい」経験です! Mac OS XにはXcodeが付属していてすぐにプログラミングが体験できます。この点現在職業としてプログラムを作っていない学生さんや一般ユーザーがプログラムを体験するには良い条件と思います。

     Macプログラマの裾野を広げるには最適の一冊です。

    ▼出版社のweb (詳しい目次あり)
    http://www.bnn.co.jp/books/title_index/mac/cocoa.html

    ▼著者のweb
    http://hmdt.jp/books/enjoyCocoa/index.html

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

     

     MOSA Developer News   略称[MOSADeN=モサ伝]
            配信停止 mailto:mosaden-ml@mosa.gr.jp
     記事内容に関するご意見 mailto:mosaden-toukou@mosa.gr.jp
          記事投稿受付 http://www.mosa.gr.jp/?page_id=850
    Apple、Mac OSは米国アップル社の登録商標です。またそのほかの各製品名等
    はそれぞれ各社の商標ならびに登録商標です。
    このメールの再配信、および掲載された記事の無断転載を禁じます。
    特定非営利活動法人MOSA  http://www.mosa.gr.jp/
    Copyright (C)2007 MOSA. All rights reserved.

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

    2007-07-24

    目次

    • 「「Wonderful Server Life」    第51回   田畑 英和
    • 小池邦人のCarbon視点でCocoa探求    
    • ターミナルの向こうから      第6回  海上 忍 

    「Wonderful Server Life」  第51回  田畑 英和

    ■  〜環境設定編〜

     今回は環境設定についてさらに詳しく解説していきたいと思います。前回の解説では、コンピュータリストのアカウントに対して環境設定を行う方法をみてきました。管理対象となるアカウントはコンピュータリストだけではありませんので、同様の環境設定はユーザアカウントやグループアカウントに対しても設定できます。
     では異なる環境設定をユーザ/グループ/コンピュータリストに対して行った場合は、どのような結果になるでしょうか。
     そもそも、いずれかのアカウントで設定した環境設定は、他のタイプのアカウントでは重複して設定しないようにすれば、なにも悩むことはなくシンプルな構成になります。ですが、実際には異なるタイプのアカウントに、環境設定の同じ項目を設定することは可能です。

    ◇環境設定の上書き
     前回の例では、コンピュータリストに対してDockの位置を「右」に設定しました。さらに、グループとユーザに対して以下のような設定を行った場合どのような結果になるかをみてみましょう。

    「Dockの位置」の設定例
     ・グループ
       「下」
     ・コンピュータリスト
       「右」
     ・ユーザ
       「左」

     Dockは左/下/右のいずれかの位置にしか表示できませんので、すべての設定が反映されることはありません。ですので3つの設定のうち、いずれか1つが反映されることになります。どの設定が反映されるかですが、アカウントのタイプによって次のような優先順位が決まっています。

    ・環境設定の優先順位
      ユーザ > コンピュータリスト > グループ

     つまり、今回の例ではユーザレベルの環境設定が優先され、該当するユーザでログインした場合、Dockは「左」に表示されることになります。もし、ユーザレベルでの環境設定がなければ(あるいは「Dockの位置」の環境設定が行われていないユーザであれば)、コンピュータリストの設定が優先されて、Dockは「右」に、グループの環境設定しかなければ、Dockは「下」に表示されることになります。
     このように、最終的にはいずれか1つのパラメータしか設定できないような項目では、アカウントタイプの優先順位によって、設定が上書きされます。

    ◇環境設定の結合
     「Dockの位置」はいずれか1つのパラメータしか設定できませんが、他の項目では複数のパラメータを設定できるものもあります。例えば、前回紹介しました「Dockの項目」などはパラメータを複数設定可能です。
     このような項目で以下のような設定を行った場合、どのような結果になるかをみてみましょう。

    「Dockの項目」の設定例
     ・グループ
       「Quartz Composer」
     ・コンピュータリスト
       「Xcode」
     ・ユーザ
       「Interface Builder」

     Dockには複数のアプリケーションを登録することができます。該当するユーザでログインした場合、Dockにはグループ/コンピュータリスト/ユーザに対するすべての設定が結合された状態で反映されます。つまりユーザに対して設定したアプリケーションだけではなく、コンピュータリスト/グループに対して設定したアプリケーションもDockに登録されます。
     このように、複数のパラメータを設定可能な項目では、上書きではなく該当するすべての設定が結合されます。

    ◇環境設定のコツ
     環境設定には「上書き」と「結合」の2種類があることが分りました。ですので、無計画に環境設定を行いますと、異なるタイプのアカウントに対する設定が影響し、意図した環境設定が実現できないような場合も考えられます。
     そこで、基本的な方針としては、異なるタイプのアカウント間で重複した設定を行わないことが考えられます。設定が重複していなければ、「上書き」や「結合」が発生することもありませんので、見通しの良い環境設定を行うことができます。
     もちろん必要があれば、「上書き」や「結合」を利用することもあるでしょうが、その場合は十分計画的に行うようにしましょう。

     さて、今回は重複した環境設定がどのように処理されるかを解説しました。次回はユーザが複数のグループに所属していた場合、環境設定がどのように反映されるかを解説したいと思います。
    つづく                                

    小池邦人のCarbon視点でCocoa探求(2007/07/20)

    〜 情報収集の日々 〜

    さて、さっそく開発を始めましょう(ワクワクしますね!)。と言っても、まずはCocoaに関する情報収集を行い、開発に最低限必要な技術を習得しておきます。まず最初に調べるべきは、米国と日本のApple社デベロッパーサイトでしょう。Cocoaに関するすべての情報(リソース)には、以下のページを入り口としてアクセスすることが可能です。

    ・AppleデベロッパーサイトCocoa関連入り口

    http://developer.apple.com/cocoa/

    初心者がこのページで最初にチェックするのは「Fundamentals」と「APIReference」の2カ所だと思います。そのうちCocoa API(クラスとメソッド)の状況を大まかに把握するために、まずはAPI Referenceの方を参照してみましょう。

    ・AppleテベロッパーサイトCocoa API Referenceページ

    http://developer.apple.com/referencelibrary/API_Fundamentals/Cocoa-api-date.html

    すると、ページタイトルは「Cocoa Frameworks」となっています。Cocoaで最大かつ最も利用されるFrameworkは「Application Kit」と「Foundation」の2つですので、まずそれらのドキュメントをダウンロードしてみます。

    「Application Kit Framework Reference」
    
    http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/ObjC_classic/index.html
    
    「Foundation Framework Reference」
    
    http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/index.html
    


    「Application Kit」とはCarbonの「HIToolBox」に相当し、ユーザインターフェース構築に関わるクラス(Carbonで言うところのマネージャ)が集められています。つまり、「もう64Bit化しない」とAppleが宣言した部分がHIToolBoxであり、「代わりに使いなさい」と推奨されたのがApplication Kitと言うわけです。もう片方の「Foundation」は、Carbonの「CoreFoundation」に準じるFrameworkです。つまり、もしCarbonアプリケーション開発時にCoreFoundation APIに慣れ親しんでいたとしたら、Cocoaの半分のクラスやメソッドの習得については、それほど労力を必要としないかもしれません(希望的観測)。

    また、OpneGL、CoreGraphics、CoreAudio、QuickTimeといったCarbonでもお馴染みのFrameworkはCocoaとCarbonの両方から利用できますので、これらで習得した技術はそのままCocoaでも生かすことができます。ただし現状のQuickTimeについては、HIToolBoxと同じく「64Bit化しない」と宣言されていますので、これから使用する場合には注意が必要です。QuickTimeは、そのうち「CoreQuickTime」とかに名称変更されて(笑)リニューアル再登場するかもしれませんね。でないと、「QTKit」(CocoaのQT関連Framework)に存在しない機能は64Bitアプリケーションで利用不可となり、メディア関連の開発では問題が噴出しそうな気がします…。

    さて、話をApplication KitとFoundationのドキュメントに戻します。両者の内容を調べてみると、両Frameworkのクラス数はそれぞれが150以上、「Application Kit Framework Reference」が約3000ページで「FoundationFramework Reference」が約2000ページの内容となっています。最低限の説明しか記載されていないリファレンスでさえこのページ数です! とてもじゃないですがメソッド数は数える気にもなりません(笑)。加えて、内容は英語ですから、技術習得の効率を考えれば、日本のデベロッパーサイトに和訳があることを期待してしまいます。それでは、日本のデベロッパーサイトを調べてみましょう。

    ・Appleデベロッパーサイト(日本)翻訳ドキュメントサイト

    http://developer.apple.com/jp/documentation/japanese.html

    Cocoa関連で翻訳されているドキュメントは以下のみです(それも半分はMOSAサイトにあります)。

    ・Cocoa基礎ガイド(Fundamentals) (PDF 7.8MB)
    ・アプリケーションアーキテクチャ入門 (PDF 1.1MB)
    ・Objective-C プログラミング言語
    ・Cocoa バインディング入門
    ・キー値コーディング(Key Value Coding)
    ・キー値監視について(Key Value Observing)
    ・Core Data プログラミングガイド

    ・Document-Based Applications Overview抄訳(MOSAサイト)
    ・Cocoa Drawing ガイド抄訳(MOSAサイト)
    ・Cocoaテキストシステム抄訳(MOSAサイト)
    ・Text System オーバービュー
    ・Text System Storage Layer オーバービュー
    ・String プログラミングガイド
    ・Attributed Strings プログラミングガイド

    残念ながら両Frameworkのリファレンスの和訳は存在しません。それにしても、最低限この2つの和訳ぐらいは存在していてもバチは当たらないと思うのですが…。上記の一覧のうち、バインディング、キー値コーディング、キー値監視、Core Dataに関するドキュメントは、割と最近Cocoaに導入された新技術の解説です。ですから、これからCocoaに取り組もうという人には、まだあまり必要ないと思われます。それより、MOSAで行った抄訳ドキュメントの方が即戦力として役に立つでしょう。ちなみに、MOSAのドキュメントサイトから貼られているリンクはもう古くなっており(涙)正しくは以下の場所にあります。

    「MOSAテクニカルドキュメント要約ライブラリ」

    http://www.mosa.gr.jp/?page_id=19

    また、MOSA伝でも記事を書いていただいた木下誠氏の「Cocoa入門ビデオ」(初級編、中級編、上級編)がムービーとして登録されていますので、こちらを最初から通しで見れば、Cocoaの全体像や開発手順を把握することが容易になると思われます。

    さて、Apple社のCocoa関連の日本語ドキュメントがここまで貧弱だと、外部から出版されているCocoaプログラミングに関する書籍に頼るしかありません。今回、筆者が連載中に参考にしようと考えているのは以下の3冊です。

    「Objectve-C Mac OS X プログラミング」萩原剛志著
    「Mac OS X Cocoa プログラミング」アーロン・ヒレガス著 村上雅章訳
    「Happy Macintosh Developing Time」木下誠著

    Objective-Cの習得には萩原氏の「Objectve-C Mac OS X プログラミング」が最適です。Cocoaプログラミング技術の習得にはアーロン・ヒレガス氏の「MacOS X Cocoa プログラミング」を、Cocoaの最新技術のチェックには先ほどの入門ビデオでも紹介した木下氏の「Happy Macintosh Developing Time」を参考にします。ちなみに、木下氏の「Happy Macintosh Developing Time」はエディションにより内容がまったく異なりますので(表紙が赤と黒)、購入時には注意してください(赤い方が最新)。

    これらの書籍と日本語翻訳ドキュメントでカバーしきれない箇所は、その都度適切な英語ドキュメントを探して紹介したいと思います。さて、これで資料の準備は完了。次回からは、いよいよXcodeとInterface Builderを起動しCocoaプログラミング・ワールドの探求へと突入します。
    つづく                                

    ターミナルの向こうから      第6回  海上 忍

    〜強力無比なエディタ「Emacs」を使う(2)〜

     Emacsでなにができるか、その実力の一端を紹介した前回に続き、今回はAquaで動くEmacs「Carbon Emacs」を例に、基本的な環境設定の方法を紹介する。

    ・「.emacs.el」を用意しよう
     前回、Emacsは起動時に「.emacs.el」というファイルを参照すると書いたが、ドットファイルはFinderに表示されない(ファイルダイアログにも現れない)ため、通常の方法ではファイルを開くことすらできない。Carbon Emacsの場合なくても動作する — 日本語環境向けの初期設定が適切に施されているため、なくてもそれなりに使える — ものの、使いやすくカスタマイズするためには、やはり「.emacs.el」が必要だ。
     はじめてCarbon Emacsを使う場合には、ターミナルから以下のとおりコマンドを実行しよう。最初の行ではtouchコマンドで空のファイルを作成、次の行ではopenコマンドを利用しテキストエディットでファイルを開く、という作業内容だ。なお、コメント行(2つ以上並んだセミコロンで始まる)に日本語を使うときは、保存時にエンコーディング形式として「日本語(ISO 2022-JP)」を指定すること。

    - - - - -
    $ touch ~/.emacs.el
    $ open -e ~/.emacs.el
    
    注:「~」はホームディレクトリを意味するシェルの記号
    - - - - -

     これで「.emacs.el」が編集可能になったわけだが、Emacs-Lispを理解しないかぎり自由なカスタマイズは不可能。誰もが時間をかけて文法を学べるわけではないので、まずは他のCarbon Emacsユーザの設定を拝借することからはじめよう。特に前回も紹介したCarbon Emacsの配布サイトには、有用な情報が満載されているので、使い始めのうちはお世話になるはずだ。
     以下に示すリストは、筆者が利用している「.emacs.el」のうち、重要かつ便利と思われる設定を抜き出したもの。各行の意味するところを、順を追って説明してみよう。

    - - - - -
    1: ;; -*- Coding: iso-2022-jp -*-
    2:
    3: ;; file coding
    4: (set-default-coding-systems 'sjis-dos)
    5:
    6: ;; more colorful
    7: (if window-system (progn
    8:   (tool-bar-mode nil)
    9:    (setq initial-frame-alist '((width . 80) (height . 30)))
    10:    (set-background-color "RoyalBlue4")
    11:    (set-foreground-color "LightGray")
    12:    (set-cursor-color "dim gray")
    13: ))
    14:
    15: ;; save cursor position
    16: (load "saveplace")
    17: (setq-default save-place t)
    18: (setq save-place-file "~/.emacs.d/save-places")
    - - - - -
    


     まずは1行目から。(.emacs.elの)コーディングシステムが正しく判定されないことがあるため、先頭行に記述する一種のおまじないだ。これで、必ずISO-2022-JPのファイルとして読み込まれる。
     4行目では、作業内容をファイルとして保存するときに適用する文字エンコーディング形式を指定する。Carbon Emacsの初期値ではUTF-8が指定されているが、まだMac OS XではS-JISのほうが出番が多いため、筆者は「sjis-dos」(改行コードはCRLF)としている。ちなみに、「sjis-mac」とすると改行コードはCR、「sjis-unix」とするとLFだ。
     7〜13行目では、画面サイズを横80×縦30字としたうえで、背景色に濃いめの青(RoyalBlue4)を、文字色に明るい灰色(LightGray)を、カーソルの色に濃い灰色(dim gray)を指定している。長時間のコーディングに耐える配色を、試行錯誤して調整するのも一興だろう。
     16〜18行では、saveplaceというEmacs-Lispで記述されたプログラムを呼び出している。このように記述すると、ファイルを閉じたときのカーソル位置を記録し、次回ファイルを開いたときその位置にカーソルを移動する働きをもつので、中断した作業をすばやく再開できる。

    ・フォントを着替えよう
     Carbon Emacsでは、Mac OS X標準のフォントパネルを利用できる。
    [Options]→[Show/Hide]→[Font Panel]を選択し、ヒラギノなど任意のフォントを指定すれば、画面全体のフォントがデフォルトのOsakaフォントから変更されるはずだ。しかし、英数字と漢字・かなとの表示のバランスや、「.emacs.el」に設定を残せないことを考えると、この方法がベストとは思えない。
     いろいろ試した結果、細身のフォントデザインで知られるエヌフォーの
    「Tokyo-等幅」フォントと、apple-monacoの組み合わせが、筆者にとってもっとも作業しやすいフォント環境となった。以下にリストを示すので、もしTokyo-Font for Internetを所有しているのならば、「.emacs.el」の末尾にでも書き加えていただきたい。

    - - - - -
    ;; Tokyo-font Touhaba
    (if window-system (progn
     (create-fontset-from-fontset-spec
     (concat
    "-*-fixed-medium-r-normal-*-14-*-*-*-*-*-fontset-tokyo14,"
    "japanese-jisx0208:-apple-tokyo 等幅-medium-r-normal--14-140-72-72-m-140-jisx0208.1983-sjis,"
    "ascii:-apple-monaco-medium-r-normal-*-14-*-*-*-*-*-mac-roman"))
     (set-default-font "fontset-tokyo14")
     (setq default-frame-alist (append '((font . "fontset-tokyo14"))))
    ))
    - - - - -
    


     今回はCarbon Emacsの設定に終始してしまったが、集中して作業(コーディング/執筆)するためにも、テキストエディタだけは軽視できないということでお許しいただきたい。次回は、LaTeXの紹介とMac OS Xへの導入方法について解説する予定だ。

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

     

     MOSA Developer News   略称[MOSADeN=モサ伝]
            配信停止 mailto:mosaden-ml@mosa.gr.jp
     記事内容に関するご意見 mailto:mosaden-toukou@mosa.gr.jp
          記事投稿受付 http://www.mosa.gr.jp/?page_id=850
    Apple、Mac OSは米国アップル社の登録商標です。またそのほかの各製品名等
    はそれぞれ各社の商標ならびに登録商標です。
    このメールの再配信、および掲載された記事の無断転載を禁じます。
    特定非営利活動法人MOSA  http://www.mosa.gr.jp/
    Copyright (C)2007 MOSA. All rights reserved.

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

    2007-07-17

    目次

    • 「りんご味Ruby」       第7回  藤本 尚邦
    • 藤本裕之のプログラミング夜話   #118
    • 高橋真人の「プログラミング指南」  第116回
    • 書籍紹介             Programming with Quartz

    りんご味Ruby   第7回  藤本 尚邦

    先月(6月9-10日)、東京で「日本 Ruby 会議 2007」が開催されました。Sunの支援により開発されているJRuby(Java VM上で動くRuby処理系)、Dave Thomasさんによる印象深い基調講演、他にもネタに走った内容の発表など幅広い内容で、運営も含めたいへん素晴らしい会議でした。

    そんな中、私もRubyCocoa作者として発表させていただきました。発表の冒頭で、RubyによるCocoaライブプログラミングをデモしました。Ruby会議用に準備したインタラクティブプログラミングのためのRubyCocoaアプリケーションCocoaReplを用いて、WindowやViewをインタラクティブに構成していく様子を示す簡単なデモです。QuartzComposerを使ったのが効いたのか、まずまず好評だったような気がしています。

    ということで、今回は、そのときのライブプログラミングで書いたRubyCocoaプログラムついて解説します。

    -----------------------------------------------
    include OSX
    require_framework "QuartzComposer"
    mw = NSApp.mainWindow
    w = NSWindow.alloc.
     objc_send(:initWithContentRect, [0,0,800,600],
                         :styleMask, NSTitledWindowMask,
                           :backing, NSBackingStoreBuffered,
                             :defer, false)
    w.makeKeyAndOrderFront(self)
    v = w.contentView = QCView.alloc.init
    qtz = "/Developer/Examples/Quartz Composer/" +
     "Motion Graphics Compositions/Cube Replicator.qtz"
    v.objc_methods.grep /^load/i
    v.loadCompositionFromFile(qtz)
    v.startRendering
    w.zoom(self)
    w.title = "RubyCocoaでインタラクティブにWindowとViewを構成した様子"
    mw.alphaValue = 0.7
    -----------------------------------------------
    


    新しく生成したウィンドウにQCViewを埋め込んで、そこにQuartzComposerファイルをロードし、アニメーションのレンダリングを開始する、というのがおおよその流れです。

     ・QuartzComposerフレームワークをロード (2行目)
     ・CocoaReplのウィンドウにmwと命名 (3行目)
     ・ウィンドウを新規生成してwと命名 (4-8行目)
     ・QCViewを生成してw.contentViewにセットし、さらにvと命名 (10行目)
     ・vにQuartzComposerファイル(Appleによるサンプル)をロード (14行目)
     ・qtzアニメーションのレンダリング開始 (15行目)
     ・wを最大化 (16行目)
     ・wにタイトルをセット (16行目)

    CocoaReplには、Rubyプログラムを評価するコマンドが3つあります。それぞれ、行・選択範囲・テキストエリア全体をRubyプログラムとして評価します。上のプログラムを1行ずつ順に入力して行を評価していくことにより、最終的には、ウィンドウの中でQuartzComposerにあるアニメーションのレンダリングが始まります。新規ウィンドウの生成と、qtzにファイルパスをセットしている部分だけは、メールの折り返しの都合により1行に書くことができませんでした。この2カ所のみ、複数行を選択して評価する必要がある点に注意してください。

    ■ まとめ

    第3回で、動的な開発環境やREPLへの思い入れについて書きました。私が、動的な開発環境の魅力に目覚めたきっかけはRubyとEmacs(最近の海上さんの連載でも取り上げられていますね)です。このデモで使っているCocoaReplはまだまだおもちゃの域のものですが、RubyとMac OS Xを結びつけて、EmacsとMacの良いとこ取りをしたおもしろいアプリケーション環境を作れないかなぁと考えたりしています。

    ■ [補足] URL

    CocoaRepl(Ruby会議バージョン)は、以下のURLから入手可能です。
    http://www.fobj.com/hisa/d/20070611.html#p01

    CocoaRepl
    http://rubycocoa.sourceforge.net/rubykaigi2007/CocoaRepl-20070624.zip

    今回紹介したRubyCocoaプログラム
    http://rubycocoa.sourceforge.net/rubykaigi2007/opening.rb

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

     お待たせ。前回の続き,別の nibファイルから読み込んだビューの上にあるボタンなどのコントロールをどうやってプリンシパルクラスがアクションを受け取るか,という話である。
     ちょっと考えてみてもやり方はいくつかある。最もCarbon的(?)なのはビュー上のコントロール一個一個について setTarget: と setAction: をやっていくことだが,普通そんなかったるいことはしないだろ。とりあえずは独立した nibファイルのなかで,それらのコントロールからのアクションをFile’s Owner である MyTabViewController(前回定義したNSWindowControllerのサブクラス)で受けるように設定してしまおう。ビュー
    に普通のボタンが3つあるとして,それぞれのアクションメソッドとして

    - (IBAction)button1:(id)sender;
    - (IBAction)button2:(id)sender;
    - (IBAction)button3:(id)sender;
    


    を作り,ボタンをこれらに結びつける。この状態で Interface Builderにスケルトンを作らせると,そのヘッダーファイルはこんな風になる。

    /* MyTabViewController */
    #import 
    
    @interface MyTabViewController : NSWindowController {
    }
    - (IBAction)button1:(id)sender;
    - (IBAction)button2:(id)sender;
    - (IBAction)button3:(id)sender;
    @end
    


     さてこっからだ。本物の…というか実際にこれらのメッセージを受けたいのはこのオブジェクトを nibファイルから読み出して初期化する方なので,そいつの情報を受けとるメソッドとその情報を格納しておくインスタンス変数を作らなければならない。すなわち,

    id _target;

    というインスタンス変数と,

    - (void)setTaget:(id)target ;

    というメソッドになるわけだが,ここでちょっと考えよう。この,_target に対してどんなメッセージを送る? もちろんその意味するところは「ボタン1が押された」「ボタン2が押された」「ボタン3が押された」なんだけどさ。

     オレ思うに,最も間違いが少ないのはそこにこのオブジェクトと同じ3つのアクションメソッドがあることである。そこで上の MyTabViewController の定義の上に,これらのアクションメソッドを持つプロトコルの定義を加えてしまう。

    @protocol MyTabViewOwner
    - (void)button1:(id)sender;
    - (void)button2:(id)sender;
    - (void)button3:(id)sender;
    @end

     プロトコルって何だ? という人はなんか Objective-C の入門書を読んで欲しいが,簡単に(そして乱暴に)言えば,ある機能を実現するためにいくつかのメソッドを定義して,それらのメソッドを持つオブジェクトを(クラスに関わらず)同じように扱うための仕組みである。よく例に挙げられるのは「ミュージックプレイヤー」という概念がこれに似ている。使うメディアはメモリだったりハードディスクだったりCDだったりMDだったりいろいろだが,少なくとも「プレイ」「ストップ」という2つの機能は持っている(「ポーズ」もかな?)。で,それらの機能を「ミュージックプレイヤー」というプロトコルでくくってしまうと,いろんな機械を「ミュージックプレイヤー」として抽象化して扱えるわけ。この話自体が抽象化されててわかんない? 使えばすぐ分かるようになるよ。

     プロトコルの定義をしたら,_target と setTarget: の定義も以下のように変える。

    id      _target;
    
    - (void)setTarget:(id  )target;
    


     この意味は,_target はオブジェクト(id)だけど,このオブジェクトはMyTabViewOwner というプロトコルに準拠してます。setTarget: の引数もオブジェクト(id) だけど,このオブジェクトはMyTabViewOwner というプロトコルに準拠してます,ということ。具体的に言うと,こいつらは button1: ,button2:,button3: というメソッドを持っていないといけないのだ(こう書いておけばコンパイルラがワーニングを出してくれる)。

     では次回こそこの話題の最終回(ホントは今回終わる予定だったんだがな)。今回定義したメソッドを具体的にコーディングしておしまいである。
                                (2007_07_11)

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

    プログラマのためのオブジェクト指向再入門(24)

    〜XcodeによるPowerPlant X入門(7)〜

     こんにちは、高橋真人です。1回間が空きましたが、続けます。
     続いて、MyApplication.cpの方を見てみます。DoCommandProcess()で、
    HICommandのcommandIDを見て分岐処理をしていますが、これはこの関数が呼び出されるのは必ずHICommandのイベントがアプリケーションに到達した場合に限っているからです。また、この関数が呼び出された時点でinCommandの中には、イベントから取り出されたHICommandの値が入っているのです。
     そういうわけで、この関数の中では、単にcommandIDの値によってどのコマンドであるのかを判断して必要な関数を呼び出せばよいということになります。今回は、渡ってくるcommandIDは、kHICommandNewとkHICommandCloseの2つのみですので、このような形でswitch文で分岐をしていますが、実際のCarbonイベントモデルのプログラミングでは、このイベントによる処理の分岐を状況に応じてきめ細かく切り替えることが重要になってくることもあるので、PPxではこのようにswitch文を使ったコマンドの分岐処理を余り行いません。
     その代わりにどのようなやり方をするのかということについては、次に行うプログラム例の時に解説します。

     さて、残りの関数を簡単に説明しましょう。
     HandleNew()では、Windowを作成して表示しています。CreateWindowFromNib
    という関数でNibファイルからWindowを読み込んできています。
     NibDecoderというのは、一見クラスのように見えますが、これは実はただのnamespce(名前空間)です。つまり、CreateWindowFromNib()という関数は、いずれのクラスにも属さない関数です。

     Cにおける普通の関数をC++では「グローバル名前空間にある関数」などと呼んだりします。しかし、プログラムのどこからでも見えてしまうために大規模なプログラム、特に複数の人間で一つのプログラムを作る際には、「出来る限り使わない」ことが望ましいとされています。
     全く別の関数が、たまたま同じ名前になっていたりすることでトラブルになることもあり得るからです。よってこの種の関数は、通常はむき出しにせず、何らかの名前空間に入れることが推奨されるわけです。
     では、何でわざわざPPxとNibDecoderという二つの名前空間を二重にかぶせるのか言えば、それは機能のグループ分けをしているわけです。
     Javaでは、すべてのメソッド(C++でいう関数)は必ずいずれかのクラスに属していなければなりませんが、C++ではどちらでも可能です。
     Java的な書き方をするなら、一つのクラスを定義してそこに属する関数をすべてstaticにしてしまうことで可能ですが、そうすると、作る必要がないにも関わらず、そのクラスのオブジェクトを作ることもできてしまいます。
     あくまで機能をグループ分けしたいだけであれば、そのためだけにクラスを作る必要は全くないので、C++では名前空間を使うわけです。(もちろん、クラスを作っても間違いではありません)
     ちなみに、クラスを作り、staticな関数にしても、クラスの代わりに新たな名前空間を使っても、呼び出す側の見た目は全く変わりません。

     話を戻します。
     さて、CreateWindowFromNibはテンプレート付きの関数になっています。これは、Windowクラスのサブクラスを作る場合にも簡単にできるためにこのようなやり方になっているのですが、理屈を説明するよりも、実際にWindowのカスタムクラスを作る手順をお見せした方がずっと理解しやすいので、ここでは説明はしません。
     とりあえず、使い方のパターンとして、PPx::WindowかそれのサブクラスをWINDOWと表すと、

    WINDOW *win = PPx::NibDecoder::CreateWindowFromNib(nibの名前, windowの名前);

    のような使い方をします。引数の、「nibの名前」、「windowsの名前」はCFStringで与えます。

    ::RepositionWindow(theWindow->GetSysWindow(), nil, kWindowCascadeOnMainScreen);

    という文ですが、まず、この関数のように先頭に::が付いているものは、先ほど触れたグローバル名前空間に属することを明示的に表す時に使います。
     C++においては、Cの関数はすべてグローバル名前空間に属するわけですが、PowerPlantからの習慣として、Toolboxというか、Carbonなどのシステムが提供するAPI呼び出しは::を付けることで区別をしやすくしています。
     次に、HandleClose()です。

    PPx::Window* win = PPx::Window::GetWindowObject(theWindow);

     GetFrontWindowOfClass()によりアクティブなウインドウが得られますが、(純粋なCarbonの呼び出しについては、PPx固有のものではないので解説はしませんから、適宜Appleサイトのリファレンスなどで確認してください)これはPPxによって作ったWindowクラスのオブジェクトです。(HandleNew()の中で作ったもの)
     なので、WindowRefからPPx::Windowに変換をします。変換に成功すれば、

    win->Close();

    と、閉じるだけです。
     ちなみに、PPx::Windowとして作っていない「タダのウインドウ(WindowRef)をPPx::Windowに変換しようとすると、もちろん失敗します。
     PPx::Windowが表示しているWindowはWindowRefのウインドウそのものですが、プログラムから見た時には、それにいくつかの付加情報が加えられたPPx::Windowクラスのオブジェクトになりますので、念のため。
     ところで、この関数が呼ばれると、

    ::CFShow(CFSTR("HandleClose called."));

    という文が実行されてHandleClose called.とXcodeの実行ログに表示されるように見えるのですが、何故か表示されません。というか、ウインドウが一つもない時にメニューから「閉じる」を選ぶと、表示されるのです。
     もちろん、これは「おかしい」のですが、説明のためにわざとやっています。

    ・なぜ、Windowを閉じる時には、このメッセージが表示されないのか
    ・Windowのない時に、メニューから「閉じる」が選べてしまうのを防ぐには
     どうしたらいいのか

    については次のプログラムで解説します。
     さて、最後に残ったClassName()という関数ですが、これは、クラス構造をファイルなどに格納する場合に必要な情報を提供された仕組みだと私は思うのですが、今のところこれが有効に使われているという気がしないのも事実です。

    書籍紹介                 Programming with Quartz

     解説担当:高橋政明

    Programming with Quartz      2D and PDF Graphics in Mac OS X
     David Gelphman、Bunny Laden共著
     ISBN: 978-0-12-369473-7

     AppleのCocoa Drawing Guideに参考文献として載っている本(洋書)です。
    Quartzを使ってどのように描画するか詳しい解説とサンプルプログラムが載っていてMac OS X 10.4対応です。著者のDavid Gelphman氏はアップルのグラフィックスイメージングチームのソフトウェアエンジニアで二十年以上にわたりQuartzの心髄であるPostScriptとPDF関連の開発に従事したそうです。

     洋書もインターネットを使い費用も納期的にも手軽に発注できるようになりましたが、本の中身がわからなければ購入の決断ができないと思いご紹介しようと思いました。でも中身も立ち読み的な参照は可能なのですね。
    http://www.amazon.co.jp/gp/reader/0123694736/ref=sib_rdr_fc/249-6059979-7374735?ie=UTF8&p=S001&j=0

     上記amazonのサイトで目次と索引に加えて最初の章を少し読む事ができます。
     OSのバージョンに依存する機能の解説部分は10.2 10.3 10.4などのアイコンがつきタイトルの(Jaguar)(Panther)(Tiger)でも明示されています。
     Mac OS Xのグラフィック能力を完全に利用し理解したいと思っている、PDFをサポートしたい、あるいはアプリケーションのグラフィック能力を高めたいCocoaとCarbonプログラマ向けの本だそうです。
     情報量はとても多く読破するのは大変ですが、サンプルプログラムと結果の画像が対になっているものが多く画像から必要な処理を探すような使い方もできます。
     2005年暮れに出版されたため、Intel Mac(Universal Binaries)についての解説もあります。私もぱらぱらと眺めただけですが基礎から、イメージやマスク、色、文字テキスト、パフォーマンスやデバグまで網羅されています。

    ▼出版社のweb
    http://www.elsevier.com/wps/find/bookdescription.cws_home/706409/description

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

     

     MOSA Developer News   略称[MOSADeN=モサ伝]
            配信停止 mailto:mosaden-ml@mosa.gr.jp
     記事内容に関するご意見 mailto:mosaden-toukou@mosa.gr.jp
          記事投稿受付 http://www.mosa.gr.jp/?page_id=850
    Apple、Mac OSは米国アップル社の登録商標です。またそのほかの各製品名等
    はそれぞれ各社の商標ならびに登録商標です。
    このメールの再配信、および掲載された記事の無断転載を禁じます。
    特定非営利活動法人MOSA  http://www.mosa.gr.jp/
    Copyright (C)2007 MOSA. All rights reserved.

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

     2007-07-10

    目次

    • 「「Wonderful Server Life」    第50回   田畑 英和
    • 小池邦人のCarbon視点でCocoa探求     ★新連載★
    • ターミナルの向こうから      第5回  海上 忍 

    「Wonderful Server Life」  第50回  田畑 英和

      〜環境設定編〜

     今回は、環境設定の設定方法について解説します。まず、次のような要件があったとします。

    ◇要件1
     「各クライアントコンピュータのDockを右側に表示するようにしたい」

     もちろん、各コンピュータ上でそれぞれ設定を行ってもよいのですが、これでは手間がかかりますし、さらに次のような要件も追加されたとしましょう。

    ◇要件2
     「クライアントコンピュータ上ではDockの位置を変更できなくしたい」

     これら2つの要件を、サーバ上で環境設定を行うことにより実現してみたいと思います。まず「ワークグループマネージャ」を起動し、コンピュータリストを追加して、そこに管理対象のコンピュータを追加します。
     次にツールバーから「環境設定」をクリックします。このとき画面の左側のリストで、環境設定の管理対象となるアカウント(今回の場合は追加したコンピュータリスト)を選択しておきます。

    ・「環境設定」画面
    http://homepage.mac.com/htabata/MXS10.3/img/WGM_MCX/WGM_MCX.png

     Dockの環境設定を行いますので、右側に表示されたアイコンの中から「Dock」をクリックします。Dockの設定画面は「Dockの項目」と「Dock表示」の2つがありますが、今回の要件では表示位置を設定しますので「Dock表示」を設定します。

    ・「Dock表示」画面
    http://homepage.mac.com/htabata/MXS10.3/img/WGM_MCX/WGM_MCX_Dock02.png

     デフォルトでは「管理」の設定が「しない」となっていますが、これはサーバ上では環境設定を管理していないという意味になります。今回の要件ではクライアント上で設定を変更できなくすることが求められています。この要件を満たすには「管理」を「常に確認」に設定します。こうすることによりサーバ上で設定した環境設定をクライアント上では変更できなくなります。
     あとは表示位置を右側に変えるだけです。「画面上の位置」を「右」に設定し、画面右下の「今すぐ適用」をクリックします。

     これで2つの要件を満たした環境設定が完了しました。サーバ状で設定した環境設定が適用されるのは、次の条件を満たしたクライアントコンピュータになります。

    ・環境設定を管理するディレクトリサーバにバインドされている
    ・環境設定を設定したコンピュータリストに含まれている

     環境設定はいずれかのアカウントに対して設定を行いますので、ディレクトリサーバにバインドされていても、管理対象のアカウントに含まれていなければ、環境設定は適用されません。
     また、管理を「常に確認」するように設定しましたので、クライアントコンピュータ上ではDockの位置を変更できなくなります。具体的には、アップルメニューや「システム環境設定」での該当する設定項目がDisableになり、設定が変更できなくなります。クライアント側の設定を常に一定の状態に保っておきたい場合には「常に確認」を選択します。
     「常に確認」ではなく、「1度」に設定した場合には、サーバで管理する環境設定がクライアントに反映されますが、クライアントコンピュータ上では自由に設定を変更することができます。クライアントコンピュータ上で設定を変更した後は、その変更内容が保持されます。最初の設定はサーバ側で行うけれども、クライアント側でも自由に設定を変更したい場合には「1度」を選択します。

     今回はコンピュータリストに対して環境設定を行いましたので、管理対象のコンピュータにログインしたユーザにかかわらず、サーバ上で管理する環境設定が適用されることになります。
     環境設定はコンピュータリストだけでなく、ユーザ単位で管理したりグループ単位で管理することもできます。

     「Dock」のもう1つの設定画面の「Dockの項目」ですが、ここではDockの中にアプリケーションや書類/フォルダを追加したり削除したりすることができます。

    ・「Dockの項目」画面
    http://homepage.mac.com/htabata/MXS10.3/img/WGM_MCX/WGM_MCX_Dock01.png

     通常はクライアントごとに行う環境設定ですが、サーバ上で一元管理できますので、この機能を活用しますと、クライアント管理を効率化することができます。それでは次回も引き続き環境設定について解説をしていきたいと思います。
                                    つづく

    小池邦人のCarbon視点でCocoa探求(2007/07/06)      ★新連載★

    〜 プロローグ 〜

    前回の予告通り、今回からは、Macintosh用アプリケーションの開発で用いる
    FrameworkをCarbonからCocoaへ乗り換える過程を探求して行きたいと思います。

    ところで、単純にCocoa、Objetive-C、Xcode、Interface Builder等の使用方法を解説しているだけでは、それこそ「Cocoa入門」になってしまいますので、本連載ではCarbonとCocoaでまったく同じアプリケーションを開発する過程を紹介することで、両Frameworkのプログラミングモデルの違いを比較したいと考えています。現在Cocoaを利用している開発者も、将来には異なる開発環境へ移らなければいけない可能性もあるわけで(笑)両者を比較することは、それぞれの利用者にメリットがあると思われます。

    さて、皆さんは既にご存じだと思いますが、今年のWWDCの基調講演でLeopard(Mac OS X 10.5)における64Bit化アプリケーションのスライドが表示された時、そこには「64Bit Carbon」の記載がありませんでした。昨年のWWDCではあったので「何が起こったのだ?」と追跡してみると、どうもユーザインターフェース担当のCarbon API(HIViewやWindow Manager等)の64Bit化は行われないというのが事実だそうです。つまり、一度に4GByte以上の大容量メモリを使用するアプリケーションがユーザインターフェースを使う場合には(まあ普通は使いますよね)、CarbonでなくCocoaで開発しなさいと言うことです。

    Carbon APIが使えないのは64Bit化アプリケーションに限った話であり、従来の32Bitアプリケーションについては何も問題ありません。しかし、筆者(Carbon使い)には、今すぐ64Bit化しなくてはいけないアプリケーションが幾つかあったので、この発表を見た時は結構ショックでした。とあるセッションでは「これはApple社からのメッセージです」という意味深な発言も飛び出しましたが、これを「Carbonは64Bit化が遅れるのか…」などと良心的に解釈した人は会場に一人もいなかったと思います(笑)。素直に解釈すれば、
    「Apple社は、そのうちMac OS XのFrameworkをCocoa一本にするぞ!」と言うことを、暗黙の了解としてWWDC参加者に提示したわけです。

    しかし現実に目を向ければ、そんなに早急にCarbon APIが全部消えて無くなることはあり得ません。重要なのは「64Bit化されないのはユーザインターフェース担当のAPI」という限定が付いている点です。つまり、Carbonのうち、File Manager、CoreFoundationなど、ユーザインターフェースと直接関わらないAPI群は64Bit化されます。なぜなら、Cocoaの特定クラスにもCarbonAPIを利用しているメソッドが多数存在しますし、FinderやiTunesをはじめ、Apple社のアプリケーションでもCarbon Frameworkを利用して開発されている物が少なからず存在するからです。よって、たとえCarbonであっても、システム的に必要とされるAPIは64Bit化しておかなければ、Cocoaの完全64Bit化も不可能になるわけです。

    Carbonに関しては、Tiger(Mac OS X 10.4)で数多くのCarbon APIが
    「DEPRECATED」(そのうち無くなる)指定されているという懸念もあります。例えば、QuickDrawのほとんどのAPIは、将来的にMac OS Xから完全抹殺されることが決定されています。しかし、現在のMacintosh用アプリケーションとの互換性を考えると、今まで存在していたAPIをすぐに無くしてしまうことは難しいと考えられます。現に、LeopardにおいてもQuickDraw APIは存在しており、問題なく使用することができます。将来的に開発環境からは外される(ヘッダーファイルが無くなる)ことはあっても、APIが完全に無くなるまでにはもう少し執行猶予が与えられるでしょう。

    こう説明すると「当分はCarbonで大丈夫かな?」と思い込みそうですが、実はCarbonの将来には大きな問題点がひとつ存在しています。それは、Mac OS Xの最新機能を使うためのCarbon APIがまったく提供されなくなったことです(32bit版でも)。例えば、WebKit、QTKit、CoreImage、CoreAnimation、といったAPI群がそうです。現状では、CoreImage APIを用いているQuartzComposerや、CoreAnimation APIを使う新ユーザインターフェースのCoverFlowやImage BrowserなどはCarbonアプリケーションから直接使うことができません。つまり、Carbonアプリケーションを現状維持で存続させることは容易なのですが、ユーザの目を引く機能を追加した新版を開発したいと考えた時に大きな壁にぶつかるわけです。

    実のところ、こうした最新Cocoa API(メソッド)はCarbonからも呼び出すことも可能です。そのため、Apple社からは、CarbonからCocoaのメソッドを呼び出すサンプルソースコードがいくつか提供されています。しかし、CocoaのクラスやメソッドはCocoaプログラミングモデル上で効率的に働くように設計されているので、Carbonプログラミングモデルと混在させることは最善ではありません。また、後々のソースコードメンテナンスを考えても「チャンポン」は避けて通りたい手法です。つまり、将来を考えれば、CarbonからCocoaメソッドを呼び出してお茶を濁すことは避けるべきなのです。

    そうは言っても、初めてのプログラミングをObjective-CとCocoaから始められる人は良いのですが、C/C++とCarbonや別のFrameworkで開発作業を行ってきた人にとっての「Cocoa移行」には多数のハードルが存在します。以下に、筆者が思いついたハードルをいくつか列挙してみました。次回からは以下の項目を一つずつ確認しながら、CarbonとCocoaの両アプリケーションを同時に開発して行きたいと思います。

    (1)Objective-Cという言語の習得
    (2)Cocoaのクラスとメソッドの習得
    (3)Cocoaプログラミングモデルの習得
    (4)Interface Builderに依存した開発工程の習得
    (5)nibファイルのコンバート作業
    (6)リソースファイルからの脱却
    (7)ローカライズ手法の習得
    (8)自作Frameworkの再構築作業
    (9)クロスプラットフォームへの対応処理

    ところで、Carbonにも同様に最新APIが用意されれば、既存のCarbon開発者(メーカ)がCocoaへ移行する確率は低くなります(私も移行しないと思う)。既存の開発者に対してCocoaへの移行を促したいApple社は「Mac OS Xの最新機能を使いたければ開発をCocoaとObjective-Cへ移行しなさい!」という姑息な手を使ってきたわけです(笑)。64Bit化の中止についても、そうした作戦のひとつでしょう。まあ、Apple社の気持ちは分からないでもありませんし、iPhoneがらみを考えればCocoaへの移行は必要かもしれません。しかし、Apple社は「移行する開発者側の労力」をどうも軽く見ている感じがします。実際には大仕事が沢山あるんですけどね(やれやれ)。

    筆者は、WWDCでCocoaセッションも聞きたいので直前にその勉強をするのですが、仕事ではまったく使わないため、1年後にすっかり内容を忘れてしまいます。そしてまたWWDCの直前に勉強…そして忘却、そんな事を5年ぐらい繰り返してきました(笑)。Objective-CやCocoaプログラミングモデルの用語はある程度理解しており、簡単なサンプル(Xcodeの雛形程度)上でオブジェクト間のOutletやActionを線で結んだことはありますが、ちゃんとしたCocoaアプリケーションを開発したことは一度もありません。

    今回の連載で開発しようと考えているアプリケーションは、MOSA Exchangeにも登録されている「しんぶんし v2.1」(対称写真ユーティリティ)の新バージョンです。はてさて、いったいどうなるでしょうか(笑)。
    つづく                                

    ターミナルの向こうから      第5回  海上 忍

    〜強力無比なエディタ「Emacs」を使う(1)〜

     Mac OS Xのディレクトリ構造について一通り説明し終えたところで、今回から2回にわたり「Emacs」について紹介してみよう。エディタの概念を超越した部分もあるEmacsのこと、たった2回で説明するには無理があるが、なぜ/どうしてEmacsが根強く支持されるのか、理解の一助になれば幸いだ。

    ・文書の編集からゲームまで
     多機能とか高機能といった言葉を添えて語られることが多い「Emacs≪いーまっくす≫」。敢えて分類すればテキストエディタだが、独自のマクロ言語「Emacs-Lisp」を備えるなど、インタープリタ型のプログラム実行環境も備えている。Emacs-Lispで記述されたプログラムの豊富さこそが、Emacsの多機能さを支えているともいえるだろう。
     EmacsはMac OS Xにも標準装備されているので、その気になればすぐ利用できる。たとえば、次のコマンドラインをターミナルから実行すると、その縦横無尽な機能の片鱗がうかがえようというもの。そう、お察しのとおり、ターミナル上にテトリス風の落ち物ゲームが始まるはず。これもEmacs-Lispで記述された、歴としたEmacsの機能の1つだ。

    - - - - -
    $ emacs -q -f tetris
    - - - - -

    ・豊富な機能と「モード」という概念
     ゲームまで動いてしまうEmacsだが、そのテキストエディタとしての真価は「モード」を抜きには語れない。モードとは、ある種のテキストを編集しやすいよう振る舞いを変えるEmacsの動作基準のことで、Cのコーディングに適した機能を持つ「c-mode」、Perlのスクリプトを記述するとき役立つ「perl-mode」、近年Mac OS Xでも利用者が増加中の「ruby-mode」など、プログラミング言語ごとにモードが用意されているといっても言い過ぎではない。もちろん、Objective-C用の「objc-mode」も用意されている。
     モードは手動で変更することもできるが、プログラミング言語用のモードの多くは、対応する拡張子 — Cなら「*.c」、Javaなら「*.java」 — に関連付けられているので、多くの場合作業対象のファイルを開くだけでOK。Mac OS Xを正式にサポートした最新のEmacs 22.0、通称「Carbon Emacs」を使えば、構文が色鮮やかに強調されたソースコードを表示できるはずだ。

    ・Carbon Emacsを導入する
     Emacsは多くのUNIX系OSで動作するが、ソースコードからコンパイルするのは一苦労。Mac OS Xの場合、日本の有志ユーザの尽力によりユニバーサルバイナリ化されたパッケージ(Carbon Emacs)が公開されているので、それを利用したほうがいいだろう。本家Emacsのソースコードには含まれない、ruby-modeなど多数のプログラムが追加収録されているという利点もある。インストールは極めてシンプル、アイコン(Emacs.app)をアプリケーションフォルダへドラッグ&ドロップするだけ、というMacの流儀に沿ったものだ。

    http://homepage.mac.com/zenitani/emacs-j.html

     EmacsはMac OS Xに標準装備(/usr/bin/emacs)されているのでは? という疑問を持つ向きもあるはず。それは正解で、ターミナルから「emacs」と実行してもEmacsは起動できる。しかし、標準装備のEmacsはMac OS XネイティブのGUI(Cocoa/Carbon)を持たずターミナル内でしか利用できないため、マウスを利用した操作やフォントの表示などの点から、Macintoshユーザには馴染まないと考えられる。Carbon EmacsにはMac独特の事情を考慮したさまざまな工夫が施されているので、使い勝手という点でも断然上だろう。

    ・Emacsのお約束(その1)
     これでEmacs(以下、断りのないかぎりEmacs=Carbon Emacsとする)を利用できる環境が整ったわけだが、誰もが快適に使えるかというと答えは“否”だ。Emacsにはいくつかの約束事があり、それを知らなければ逆に使い心地の悪いものとなる。
     その1つが、命令実行時には2〜3段階の入力作業を行うことと、その表記に関する知識。ファイルの開くための操作を例にすると、[control]を押しつつ[x]を押し、その直後に[control]を押しつつ[f]を押す、という2段構えの操作が必要になる。Emacsについて調べていると、よく「C-x C-f」などという表記が登場するが、これは[control]を押しつつ[x]を押し……という操作を完結に表現したものだ。同様に「M-x」という表記も頻出するが、MacではMetaキーの代わりに[command]を使うので、[command]を押しつつ[x]を押す、と読み替えればいいことになる。
     もう1つが、設定ファイルの存在。Emacsは起動時に、カレントユーザのホームディレクトリ(「ホーム」フォルダ)に「.emacs.el」というファイルの有無をチェック、あればそこに記述された内容をEmacsの動作に反映させる。環境設定パネルという概念はなく、必要な設定は.emacs.elに書き加える、というUNIX流のスタイルだ。ちなみに、先頭が「.」で始まるファイル(通称ドットファイル)はFinder上では非表示のため、開くときには少々コツが必要なので注意しよう。

     次回は、その「.emacs.el」の基本的なカスタマイズ術と、いくつかのモードの便利な使い方を紹介してみよう。

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

     

     MOSA Developer News   略称[MOSADeN=モサ伝]
            配信停止 mailto:mosaden-ml@mosa.gr.jp
     記事内容に関するご意見 mailto:mosaden-toukou@mosa.gr.jp
          記事投稿受付 http://www.mosa.gr.jp/?page_id=850
    Apple、Mac OSは米国アップル社の登録商標です。またそのほかの各製品名等
    はそれぞれ各社の商標ならびに登録商標です。
    このメールの再配信、および掲載された記事の無断転載を禁じます。
    特定非営利活動法人MOSA  http://www.mosa.gr.jp/
    Copyright (C)2007 MOSA. All rights reserved.

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

    2007-07-03

    目次

    • 「りんご味Ruby」       第6回  藤本 尚邦
    • 藤本裕之のプログラミング夜話   #117
    • 高橋真人の「プログラミング指南」  第115回
    • 書籍紹介         エンジニアのための英会話超克服テキスト

    りんご味Ruby   第6回  藤本 尚邦

    初回で、「実践的な内容を織り交ぜながら」と書いたにもかかわらず、細かい話が続いてしまいました。そこで、今回は、簡単だけど応用ができそうな実例を示すことにします。初回に示した、MOSAのRSSを取得して内容を出力するプログラム:

    ----------------------------------------------- rss-reader.rb ---
    require 'rss/2.0'
    require 'open-uri'
    url = 'http://www.mosa.gr.jp/?feed=rss2'
    rss = open(url) { |io| RSS::Parser.parse(io.read, false) }
    puts "-- #{rss.channel.title} (#{rss.items.size} entries) --"
    puts
    rss.items.each { |item| puts item.title }
    -----------------------------------------------
    


    これをCGIプログラムに改造してみましょう。

    ■ 最も単純なRSSリーダーCGIプログラム

    ----------------------------------------------- rss-reader.cgi ---
    #!/usr/bin/ruby -Ku
    require 'rss/2.0'
    require 'open-uri'
    url = 'http://www.mosa.gr.jp/?feed=rss2'
    rss = open(url) { |io| RSS::Parser.parse(io.read, false) }
    puts "Content-Type: text/html"
    puts
    puts "

    #{rss.channel.title} (#{rss.items.size} articles)

    " puts "
      " rss.items.each { |item| puts "
    • #{item.title}" } puts "
    " -----------------------------------------------

    元のプログラムとほとんど同じですね。しかし、これでも立派なCGIプログラムです。違いは以下の通りです:

     ・1行目にこのプログラムを実行するためのコマンド(ruby)を指定 (一般にこの行のことをshebang行と呼びます)
     ・HTTPヘッダを出力
     ・HTTPのヘッダ部とホディ部を区切る空行を出力
     ・rssの内容をHTMLタグで装飾したHTMLをHTTPボディとして出力

    このファイルを /Library/WebServer/CGI-Executables/ の中にrss-reader.cgi という名前で保存してください。さらに、ターミナル上でchmodコマンドを使って実行可能にします。

     

    $ chmod +x /Library/WebServer/CGI-Executables/rss-reader.cgi

    まずはターミナル上で実行してみましょう。次のように出力されればOKです。

    -------------------------------------------------- (Terminal) ---
    $ /Library/WebServer/CGI-Executables/rss-reader.cgi
    Content-Type: text/html
    
    

    特定非営利活動法人MOSA (10 articles)

    • WWDC2007参加ツアーのお知らせ
    • FileMaker Pro 8基礎ハンズオンセミナー レポート  (中略)
    --------------------------------------------------

    それでは、CGIプログラムとして実行してみましょう。まず、パーソナルWeb共有を有効にする必要があります。システム環境設定を起動して「共有」パネルを表示してください。「サービス」タブを選択して、「パーソナルWeb共有」のチェックボックスをチェックしてください。

    これで準備は整いました。SafariなどのWebブラウザで、以下のURLを入力してください。

     http://localhost/cgi-bin/rss-reader.cgi

    うまく表示できたでしょうか? これがもっとも単純なRubyによるRSSリーダCGIです。putsを使ってHTMLを出力しています。単純なうちはともかく、複雑なHTMLを出力するためにはいろいろ工夫が必要そうですね。

    ■ プログラム本体と表示データを切り分けたCGIプログラム

    次は、ひと味違った方法を紹介しましょう。Rubyに付属するERBというライブラリを利用して、プログラム本体と表示用のHTMLデータを分離して、見通しを良くします。

    --------------------------------------------- rss-reader-erb.cgi ---
    #!/usr/bin/ruby -Ku
    require 'rss/2.0'
    require 'open-uri'
    require 'erb'
    url = 'http://www.mosa.gr.jp/?feed=rss2'
    rss = open(url) { |io| RSS::Parser.parse(io.read, false) }
    puts "Content-Type: text/html"
    puts
    puts ERB.new(DATA.read).result
    __END__
    
    
     
    
    
    

    <%= rss.channel.title %> (<%= rss.items.size %> articles)

      <% rss.items.each { |item| %>  
    • <%= item.title %> <% } %>
    --------------------------------------------- rss-reader-erb.cgi ---


    このプログラムを、前のCGIプログラムのときと同様に/Library/WebServer/CGI-Executables/ の中に保存して(ここではrss-reader-erb.cgiと名づけました)、chmodコマンドで実行可能にします。

     $ chmod +x /Library/WebServer/CGI-Executables/rss-reader-erb.cgi

    さきほどと同じように、ターミナルで確認してみて、それからWebブラウザで結果を確認してみてください。

    このプログラムは、途中の__END__を境に、上側がRubyプログラム、下側はHTMLのような表示用のデータになっています。下側のデータは、Rubyに付属するERBというライブラリを使って、取得したRSSデータを埋め込んだ実際のHTML文字列に変換して出力しています。

     

    puts ERB.new(DATA.read).result

    ERBの基本的な役割は、入力文字列の中に埋め込まれたRubyプログラムを実行して、その結果を、入力文字列中に埋め込んで出力することです。PHPをご存知の方であれば、イメージしやすいかもしれません。

    -------------------------------------------------- (Terminal) ---
    $ irb --simple-prompt
    require 'erb'
    => true
    ERB.new("hello").result
    => "hello"
    ERB.new("hello at <%= Time.now %> ...").result
    => "hello at Thu Jun 28 21:52:17 JST 2007 ..."
    ERB.new("<% 10.times {|i| %><%= i %>, <% } %>").result
    => "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
    --------------------------------------------------
    


    Rubyプログラムは <% ... %> もしくは <%= ... %> のように囲んで埋め込みます。<%...%>は、Rubyプログラムとして実行後、出力から取り除かれます。<%=...%>は、Rubyプログラムとして実行した結果を文字列として置き換えます。その他の部分は、そのまま出力されます。

    __END__については、Ruby言語の仕様として、__END__行以降、Rubyプログラムではなくデータとして扱うことができるようになっています。

     DATA.read   # __END__以下の行を文字列として返す

    今回は、RSSリーダプログラムを、CGIプログラムにアレンジする方法を2つご紹介してみました。

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

     予告通り,「ビューの中身だけを別のnibファイルから読み込む」という話である。
     実を言うと前回までの説明で,インタフェースに関わるリソースを複数のnibファイルに分割する,という話は終わったつもりでいたのであるが,「次はなにをネタにしましょうかねぇ」というメールをタカハシ編集長に出すと,折り返し「サブビューの中身を別 nibファイルに持つというケースについても解説してよ。特にそんなかに配置されたコントロールからどうやってアクションを受け取るとか」というリクエスト。
     なぁるほど,それはワタシも今までやってみたことありませんでしたわ,というわけで早速ちゃちゃっと試してみた。以下の説明,自分で作ってみれば簡単なんだけど,なにしろメールマガジンでは図が使えないので,読むだけで解ろうという横着な人には多少回りくどくなることだけ,ご了承いただきたい。

     作ってみたのは次のようなプログラム。
     起動すると一つのウィンドウが開き,その中にはタブビューが1個ある。タブビューにはタブが2個(仮に「base」と「alternative」とする)あって,初期状態では「base」が選ばれている。そのときのタブビューの表示は「こいつはこのタブビューのbaseタブの中身だぜ」というもの。
     ここまで観てきた全てのリソースは,起動と同時に読み込まれる「MainMenu.nib」に定義されている。これから何をしたいかというと,もう1つのタブ,「alternative」を押されたときにこのタブビューの内部に表示されるべきビューの内容を MainMenu.nib とは別の nibファイルとして作成・保存したいわけである。もちろんそのビューにはボタンとかのコントロールがあり,そいつらからのアクションはこのアプリケーションのプリンシパル・クラスで処理できるようにしたい……編集長,リクエストはこれで間違いないよ
    ね?

     まずは当然ながら Interface Builderを起動する。出てきた「StartingPoints」というウインドウのリストから「Cocoaのビュー」というの……はないのでさぁどうしましょう。まず上のようなことを考えた人が最初につまずくのはここぢゃないかと思う。「なんだ,ビュー単位で nibファイル作ることできねぇんぢゃん。編集長,それ,できませんわ」と,メールなどしているようではいけない。
     ここは前回まで,アバウトパネルを作ったときと同じように,「Window」を選んでしまえばいいのである。なぜか? 簡単なことでしょうが。ウインドウがひとつあれば必ずその中身としてビューが1個,あるやないの。別に nibファイルをウインドウ単位で分割したからって,そのまま使わなくちゃならないってことはないんだよね。

     この nib ファイルのウインドウの中身に,「こいつはこのタブビューのalternative タブの中身だぜ」という文字列と,それからコントロールのサンプルとしてボタンなどを配置する。続いてこれまたアバウトパネルの時と同じように File’s Owner のクラスを定義する。名前はなんでもいいが,MyTabViewController としておいた。

     Interface Builderでソースのスケルトンを作らせ,このnibファイル「TabView.nib」という名前で保存してできあがり……ではないので注意。
     このビューをあたかも MainMenu.nib に定義されたもののごとく扱うにあたっては2個ほど問題がある。まず一個は,当然ながらnib に定義されたWindowごとではなくそっから中身のビューだけ引っ張り出してMainのタブビューで表示できるようにすること。もう一個は,このビューに乗っかってるコントロール,つまりボタンを押されたとかスライダーが動かされたとかいうアクションをプリンシパル・クラスでハンドルできるようにすることである。

     では最初の課題のほうから。これは以前,この連載で書いた,不定形な(あるいはタイトルバーのない)ウインドウを出しましょう,というやつの応用で,MyApplication.hにコントローラのインスタンス変数を次のように定義し,

      

      MyTabViewController*          tabViewController;

    MyApplication.m(このクラスはタブビューのdelegateになってる)にタブビューのタブがクリックされたときに呼ばれるメソッド,tabView:didSelectTabViewItem: を書けばいい。

    -(void)tabView:(NSTabView*)tabView didSelectTabViewItem:(NSTabViewItem*)tabViewItem {
        NSString* identifier = [tabViewItem identifier];
        if([identifier isEqualToString:@"2"]){
             if(tabViewController == nil){
                  tabViewController = [[MyTabViewController alloc]
                                      initWithWindowNibName: @"TabView"];
                  [tabViewItem setView:[[tabViewController window] contentView]];
             }
        }
    }
    


     クリックされたタブの identifierをチェックし,2番目すなわち別のnibファイルから読むほうだったら必要に応じて tabViewController を初期化し,その window のcontentView だけ持ってきて(気分は「横取りして」つう感じだが)それをタブビューアイテムにセットしてしまう。簡単でしょ。では次回はもう一つの課題,いかにしてこのビュー上のアクションをこっちのクラスに持ってくるか……ここまで来ればもう答えは分かったようなもんだと思うが……分かんない人は次回を待たれよ。
                                (2007_06_29)

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

    プログラマのためのオブジェクト指向再入門(23)

    〜番外編・Carbonの将来は?〜

     こんにちは。高橋真人です。
     今回は、PowerPlant Xの解説を続ける前に触れておきたいことがあります。それは、「Carbonの今後」ということについてです。
     今年のWWDCの基調講演で、64bit Cocoaという言葉があったのに64bitCarbonという言葉がなかったということについて、「これは意図的になされたものなのか?」との疑問がApple主催のCarbon-devメーリングリストで提示されました。
     仮にそれについての詳細がその後のいずれかのWWDCのセッションにおいて語られたとしても、基調講演以外のすべてのセッションはNDAの下に保護されているため、WWDCの参加者からそれらが語られることはありません。Carbon-devメーリングリストは原則的に公開のものですから、ここでNDAベースの話が行われることはないわけです。
     ところがAppleの、しかもCarbon関連の技術者であるEric Schlegel氏があっさりと「認めて」しまったのです。ここ数年WWDCでCarbonの動向に関心を持ってセッションを受けていた私の印象では、このSchlegel氏は実質的なCarbonチームのリーダーであるというものでしたので、彼の職責上の発言の重みがどれくらいのものなのかはさておいても、彼の発言は信用に足るものだと私は思います。(*注)
     そんなわけで、公開のメーリングリストからでも、Carbonの今後を知るための情報が収集できるのです。
     まずは、くだんのメーリングリストのアーカイブが以下のサイトから閲覧できますので、興味のある方は是非ご覧になってみてください。 特に、
    http://lists.apple.com/archives/Carbon-dev/2007/Jun/thrd3.htmlのいちばん下の「64-bit Carbon」と、
    http://lists.apple.com/archives/Carbon-dev/2007/Jun/thrd4.htmlの下の方にある「Is Carbon Viable?」から始まるスレッドがこのテーマに関する中心的なものです。
     もっとも、これらは今でも続く膨大なスレッドであり、なおかつ内容は当然英語ですから、そうやすやすと読む気にもなれない方も少なくないでしょう。
     そんな方には、こちらも英語ですが、メーリングリストの参加メンバーの一人がまとめたWikiが以下にありますので、こちらを読むだけでもエッセンスは汲み取れるかもしれません。

    http://www.carbondev.com/site/?page=64-bit+Carbon

     さて、以下は私自身の個人的な見解です。当然私は、何らの権限もありませんし、保証することもできませんが、私自身が今までCarbon+PowerPlant Xで仕事をしてきた人間として今後どうして行こうとしているのかを知ることを通して、皆さんお一人お一人がご自分なりの今後の方針を立てる上での参考にしていただければと思います。

     まず、AppleがMac OS Xの発売当初からCocoaを前面に出して推進してきていることは、今Macの開発に関心を持っている方であれば当然ご存知のことです。もともとMac OS 9以前のToolboxベースのシステムからの移行環境として提供されたのがCarbonの成り立ちですから、完全にMac OS Xへの移行を済ませてしまった方々から「もはやCarbonは不要」という声を上がるのも無理のないことです。
     しかしながら、Mac OS X上で実際に開発の仕事をされている皆さんならばお分かりのように、Mac OS XというOSは実に様々なシステムが連携し合いながら動いているシステムです。その他のシステムは言うに及ばず、CarbonとCocoaの境目だって、口で言うほど明確なものではないのです。
     例えば私は、「郷に入っては郷に従え」をプログラミングに関しては徹底したい人間で、いざCocoaでプログラムを組もうとした場合には、極力Application KitとFoundation Kitに属するものだけで処理したいと考えるのですが、実際のプログラムを組む上でそれはほぼ不可能です。
     つまり、Cocoaと言うとイメージとして、Objective-Cのメッセージ構文である

    [object message];

    [object message:arg1 with:arg2];
    


    のような形の記述が目立ちますが、実際のCocoaのコードには普通のC言語の形式の関数呼び出しも頻繁に登場します。
     AppleがCocoaを推進し、さらに既存のC/C++デベロッパ、さらには他のプラットホーム上で開発をしているデベロッパに対して「あなたのC/C++のコードは、そのままObjective-C/Objective-C++のコードでもあるのだ」というようなことを言う人もいます。
     しかし、物事はそんなに単純ではありません。コードの問題のみならず、多くの過去の資産をCocoaで使うためには、「そのまま」で済まないケースはたくさんあるはずだ、ということを今までもずっと多くの人が言ってきたわけです。
     しかし、Appleがここに来て打ち出した一つの方策は、いろいろ理由を付けてCocoaに取り組もうとしないデベロッパたちの最後の砦を崩しにかかってきたことを意味すると私には思えます。
     恐らく、いちばんCocoa化が難しいのは、マルチプラットホームのプロダクトでしょう。中でもMicrosoftとAdobeという二大ソフトウエアメーカーがMacプロダクトのすべてをCocoaベースで作ることができるかということは、他のデベロッパに対しても説得力という意味で大きな影響を持つことは間違いありません。
     今回のAppleの動きは、とりあえずはしごを外してみて、屋根の上にいる人たちがどするのかをしばらく見てみようということなのではないかと思います。(屋根の上にはAppleの社員も残っているみたいですが・笑)
     つまり屋根の上のデベロッパには、一度「もう後戻りはできないのだ」と腹をくくってもらった上で真剣にCocoaに取り組んでもらう、と。
     それでも、もしどうにも立ち行かないというケースが出てきた場合、はしごを外しっぱなしにしておくかどうかは、まだ決まっていないような気がしないでもありません。
     実は、今回のAppleの動きを感じる前に、私自身は「とりあえず、軸足をCocoaに移してみようか」と思っていたのです。それは、OSのバージョンが上がるに連れて「Cocoaでしかできない機能」が確実に増えてきていること。特にLeopardで提供されるCore Animationは、将来的に世の中のパソコンの使い方すら変化させてしまう可能性を秘めた技術だと期待しているため、こういったMac OS Xの先進機能を積極的に取り入れて利用していくためにはCocoaを使うことは必須だと思っているからです。
     ところで、これまで解説を続けてきたPowerPlant Xはどうするのかということですが、まだ諦める予定はありません。今回WWDCに参加して、あくまで個人的に感じたのですが、世界にはC++プログラマはまだたくさんいるようなのです。
     ことコンピュータに関しても、新しいものが出てくると一斉に飛びつき、それまでのものを何のためらいもなく捨ててしまうことの多い日本とは違って、欧米の文化は古いものも大切に使っていく傾向があるように思います。
     進化が止まり、価値のうすれてしまったものにいつまでも執着し続けるのもどうかとは思いますが、少なくともC++という言語は現在も活発に機能強化が行われている言語です。
     PowerPlant X自体の進化は余り望めませんが、既存のC/C++の資産をCocoaに積極的に取り込んでいく上で、PPxの活用の余地は充分あるのではないかというのが今の私の考え方です。
     今後は、その観点で、いかにスムーズかつスマートに融合できるかを模索していきたいと思っています。

    【注記】その後に同氏から投稿されたメッセージによれば、「Appleからの公式見解はWWDCにおけるスティーブの基調講演と、私やAppleのDRの人間によるこのMLへの投稿だけだ」とのことでしたので、彼の個人的見解ということではないようです。

    書籍紹介           エンジニアのための英会話超克服テキスト

     解説担当:高橋政明

    エンジニアのための英会話超克服テキスト
                   -実戦!テクニカル・ミーティング-
      平井 通宏 フランシス J. クディラ 共著
      オーム社  ISBN 4-274-19735-2  定価2,520円

     タイトルが示すように我々技術者に役立つ英会話本です。(書店では技術系の書棚ではなく語学の書棚に置かれることが多いようです)
     実はWWDCに向け同じ著者の別の本を入手したのですが、この本の存在を知りこちらを読み始めました。読み始めたのが遅かった事もあり残念ながらWWDCへ向かう時点でまだ半分も読み進んでいませんでした(失敗!)

     およそ三年前に初版が出たので最新ではありませんが、電子メールについても解説されていて直接英語で話す場合に限らず役立つと思います。
     第I部基礎編と第II部応用編に分かれています。基礎編は基本的表現が分類されていて必要な部分をすぐに参照できるよう工夫された構成です。会議での英会話が中心ですがWWDCのラボような一対一の会話に必要な情報もあります。
     特に「第I部9 円滑にコミュニケーションする」では「相手の言った事に反応を示す」や「相手の言葉を理解した/しなかったことを表明する」といった項目が目次に載っています。「英語能力の不足を宣言する」は(私には)有用な情報で今回のWWDCでも役に立ちました〔^_^;〕

     文化の違いや技術的な表現について、何を言うべきか、どうすべきか、なぜそうすべきかが解説されています。フォーマルな表現とインフォーマルな表現は記号で明確に示されています。WWDCあるいは相手がAppleの技術者であればインフォーマルな表現でもほとんど問題ないと思いますが使い分けることができるにこした事はありません。

     基礎編は自己紹介からはじまっています。職位の英和対応表もあり口頭での自己紹介だけなく英文の名刺を作る場合等にも役立ちそうです。
     多数の例文が掲載されています。それぞれどのような印象を与える言い回しかも解説されているので、どの例文を採用するか検討する際に有用です。またコラムには著者の経験に基づくベテランならではのひとことが載っています。(著者の一人は日立製作所に30年間在籍された方だそうです)
     付録1にはagendaや議事録の文書化などを含む「技術打合せに関する実務上のポイント」が、付録2にはボキャブラリ索引があります。このように全体に仕事ですぐに使えるよう考えられた内容です。

     文化の違いを認識しあうことはコミュニケーションには重要ですよね。今年のWWDCは本書のおかげで少しは安心感を持って臨む事ができました。WWDCのように旅行英語だけでは不足を感じる場合や、英語でemailを書かなければならない場面で本書の情報が役にたつと思います。

    ▼出版社のweb(少し古い本なので詳細目次はありません)
    https://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=4-274-19735-2

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

     

     MOSA Developer News   略称[MOSADeN=モサ伝]
            配信停止 mailto:mosaden-ml@mosa.gr.jp
     記事内容に関するご意見 mailto:mosaden-toukou@mosa.gr.jp
          記事投稿受付 http://www.mosa.gr.jp/?page_id=850
    Apple、Mac OSは米国アップル社の登録商標です。またそのほかの各製品名等
    はそれぞれ各社の商標ならびに登録商標です。
    このメールの再配信、および掲載された記事の無断転載を禁じます。
    特定非営利活動法人MOSA  http://www.mosa.gr.jp/
    Copyright (C)2007 MOSA. All rights reserved.