MOSA Multi-OS Software Artists

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

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

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

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

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

    2008-07-29

    目次

    • りんご味Ruby         第29回  藤本 尚邦
    • 藤本裕之のプログラミング夜話   #142
    • 高橋真人の「プログラミング指南」  第140回

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

    前回は、HTMLパーサの Hpricot を使って YahooHonyaku#parse_form! を実装し、YahooHonyaku#open_top_page を完成させました。ここで、第24回で作成したtest-yahoo-honyaku.rb を使ってテストしてみましょう。

     

    $ ruby test-yahoo-honyaku.rb
     (中略)
       2) Error:
     test_translate(TestYahooHonyaku):
     NotImplementedError: まだ実装してねぇ、誰か書いてくれ!
         ./yahoo-honyaku.rb:32:in `post_text'
     (中略)
     2 tests, 0 assertions, 0 failures, 2 errors
    
    YahooHonyaku#post_text が実装されていないためにエラーになりました。と
    いうことで、今回は YahooHonyaku#post_text
    
     def post_text(mode, text)
       raise NotImplementedError, "まだ実装してねぇ、誰か書いてくれ!"
     end

    の中身を実装していくことにします。post_text は、翻訳したいテキスト(text)と何語から何語に翻訳したいか(mode)を引数にとり、Yahoo!翻訳に対してリクエスト(HTTP POST)します。そして、レスポンスのボディ部すなわち翻訳結果を含むHTMLを返します。2つの引数は、どちらも YahooHonyaku#translateの引数をそのまま引き継ぎます。

     (注) translateメソッドの引数の形式(インターフェース)は、別の翻訳システムを使って実装しても同じように使えることを考慮します

    text引数は、翻訳したいテキストの文字列です。mode引数は:

     "ab" または :ab  -- A語からB語へ
     "ba" または :ba  -- B語からA語へ
    


    というような形式にすることにします。このような形式では、世界にあるたくさんの言語すべてに対応するのには不十分かもしれませんが、話を単純にするためここは目をつぶってください。

     (注) ここで「”」で囲まれてる “ab” や “ba” は文字列です。一方、「:」で始まる :ab や :ba はシンボル(Symbol)という型(クラス)の値です。ここではシンボルについて詳しい説明は省きますが、Rubyプログラムでは、文字列リテラルを書くような場面(例えばHashリテラルのキーの値など)で、その見た目のシンプルな代用品としてシンボルがよく使われています。

    一方、Yahoo!翻訳のHTTP POSTのパラメータを調べると、eidというパラメータに何語から何語への翻訳かを指定するようになっています:

     

    eid=CR-JE     -- 日本語から英語へ   (日英)
     eid=CR-EJ     -- 英語から日本語へ   (英日)
     eid=CR-JK     -- 日本語から韓国語へ (日韓)
     eid=CR-KJ     -- 韓国語から日本語へ (韓日)
     eid=CR-JC-CN  -- 日本語から中国語へ (日中)
     eid=CR-CJ     -- 中国語から日本語へ (中日)
    


    mode引数はPOSTするためにeidパラメータの値に変換する必要がありますから、それをprivate なメソッド _eid_ として定義します。

    仮に日中変換のeidが他のパラメータと同じように単純に”CR-JC”ならば、(エラー処理のことを考えなければ)場合分けが不要になり、_eid_ の中身は単純に:

     "CR-#{mode.to_s.update}"

    だけで済んでしまうところでしたが、残念ながら条件分岐が必要になります。ここでは、case文式を使って “JC” のときの分岐を表現しました。_eid_ の定義は以下のようになります:

     

    def _eid_(mode)
       mode = mode.to_s.upcase   # modeを(Symbolなら)文字列化・大文字化
       case mode
       when "JC" then "CR-JC-CN"
       else           "CR-#{mode}"
       end
     end
    


    ■ case文式について

    もちろん、ここでは、分岐のもっともプリミティブな表現であるif文式を使うことも出来るのですが、あえてcase文式を使いました。Rubyのcase文式は、一見するとC言語のswitch文と似た感じに見えますが、オブジェクト指向言語の特性を活かした高度な仕組みを含んでいます。

    case文式は、おおざっぱに以下のような構文になります:

    case ある値
    when 条件A1, 条件A2, ... then 文式の並びA
    when 条件B1, 条件B2, ... then 文式の並びB
    ...
    else                          文式の並びN
    end
    


    thenがくるところで改行した場合はthenを省略できます。これをあえて日本語で読み下すと:

    ・ある値について:
    ・条件A1または条件A2(または…)にマッチしたら、文式の並びAを実行して、case文式の結果として返す
    ・条件B1または条件B2(または…)にマッチしたら、文式の並びBを実行して、case文式の結果として返す…
    ・いずれの条件にもマッチしなければ、文式の並びNを実行して、case文式の結果として返す

    となります。

    さて、オブジェクト指向言語の特性が活かされているポイントはどこにあるのでしょうか? それは、条件にマッチしたことの判別方法にあります。同じものを、条件分岐のもっともプリミティブな構文であるif文式を使って表現すると、おおざっぱに以下のようになります:

    if    条件A1 === ある値 or 条件A2 === ある値 or ... then
     文式の並びA
    elsif 条件B1 === ある値 or 条件B2 === ある値 or ... then
     文式の並びB
    ...
    else
     文式の並びN
    end
    


    となります。つまり、case文式を日本語で読み下したときの「条件にマッチする」は

     「条件 ==== ある値」が真である

    ということになります。この === は「条件」に相当するオブジェクトのインスタンスメソッドになっていて、所属性(という言葉が適切かどうか定かではないのですが)のチェックを意味します。

     (注) – まだ書いてなかったと思うのですが、Rubyでは、C言語で数値や論理 の二項演算子に相当するものの多く(例えば +,-,*,/,== など)が、左辺の値のインスタンスメソッドになっています。

    デフォルトの Object#=== は Object#== と同じなので、基本的には、case文式は条件との等値性をチェックということになります。しかし、一部のクラスでは、そのクラスにおける「条件にマッチした」という感覚に見合うように===が再定義されています。そのようなクラスの代表的なものとしては以下のものがあげられるでしょう:

     範囲型(Rangeクラス)         – 範囲.include?(ある値)
     モジュール型(Moduleクラス)  – ある値.is_a?(モジュール)
     正規表現(Regexpクラス)      – 正規表現 =~ ある値

    このような性質を使って、例えば以下のようなcase文式を書くことができます:

    def check_a_value(a_value)
     case a_value
     when "hello" then '"hello"という文字列でした'
     when /world/ then '"world"を含む文字列でした'
     when String  then '文字列でした'
     when 12345   then '12345という整数値でした'
     when 0..100  then '0以上100以下の数値でした'
     when Integer then '整数値でした'
     end
    end
    


    説明が込み入ってしまったため複雑に感じられてしまったかもしれませんが、このような仕組みが背景にあって、case文式は高度な条件式をシンプルに書くことが出来るようになっているわけです。

    今回は、途中からcase文式の説明になってしまいましたが、次回、引き続きpost_text の実装をする予定です。

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

     承前、iTunes Storeの売り上げばかりが喧伝されている感のある音楽のダウンロード販売だが、その商売の大部分を占めるのは実はケータイ電話への着うたであってコンピュータやiPodない。しかもコンピュータiPodにダウンロードするヒトタチ(例えばオレのことだけど)と違い、この着うたをダウンロードするヒトタチはそれを「とっておく」ことをしないで(その方法もない
    んだけどさ)惜しげもなく捨ててしまうのだ、というトコロまでハナシは進んでいたと思う。

     ほんで何が言いたいかというと、これは音楽という「ソフトウエア」の消費の仕方に訪れた「変化」なんだということなのである。何度も書くがオレのような古い……いいたかないが古いニンゲンは、音楽をCDとか、ダウンロードしてもハードディスクだのCD-Rだのというメディアに保存して「所有」する、という「消費」をしてきた。高校生のとき3個食いたい昼飯のパンを2個にして
    キース・ジャレットのレコードを買ったりしたのである。わかるでしょ?

     もちろん「所有せずに消費する」方法だっていくらもあった。音楽なんてラジオでも聴けるし、飲み屋やパチンコ屋から有線にリクエストすることだってできる(これ、やった経験のある人わりと少ないので驚くのだが)。でもオレの学生時代から流行り出した「貸レコード屋」の店頭にカセットテープが山積されていたことからも解るように、消費形態の主流はあくまで「所有」だった
    はずだ。貸レコード屋でレコード借りて、ダビングもしないで返してたヒトなんて……オトモダチにいましたか? なのに今の若いヒトはお金を払って音楽を「聞き捨て」るのである。しかもあ〜た、着うたフルってiTunes Storeで買うより高いンだぜ。

     こんなハナシもある。こないだ新聞で読んだのだが、確かにここ数年音楽CDの売り上げは落ちていて、製作会社をから街のレコード……いやCD屋さんまで大変経営が苦しくなってきている。が、では音楽産業全体がダメなのかというとそうではなく、特にライブ、コンサートなどの売り上げは増加傾向にあるというのだ。そう言われてみればコンサートなんて所有できない音楽消費形態の最たるもんではありませんか。

     こういう傾向がなぜ生まれたのか。オレは経済学者でもなければ心理学者でもないので難しい理論はわからないが(そんでそういうのって説明されてもいつもなんか納得がいかないんだが)、音楽に関して言えば未だにiTunes StoreよりもCDを購入するほうを選ぶオレが、他のモノでは確かにそういう消費形態になりつつあるのだった。うんうん確かに似てるのだ。どーゆーことかと言う
    と、オレはこのところほとんどDVD、すなわち映像ソフトを買わなくなったのである。なるほど、つーことは、オレ自身の行動のココロを探れば、この変化について何か解るかも知れぬ。

     というわけで自問してみる。なぜ最近オマエは以前ほどDVDを買わないのか?……第一の理由はもちろんビンボーだからのような気がするが、そんぢゃ以前はビンボーぢゃなかったかというと、以前もやっぱりビンボーだったよな気がするのでそれはあんまり関係ないだろう。

     ほんぢゃぁ先ほどからキーワードになっている「所有」というトコロから攻めてみよう。買わなくなったのは「所有」したいような映像ソフトが少なくなったから? そう訊かれて(自分にだけど)自分のDVD棚を改めて見返す。ここに並んでいるモノすべて「所有欲を刺激されて買った」モノか? 確かに中には手塚治虫アニメラマ三部作とか岡本喜八「大誘拐ーrainbow kids」みた
    いに「これは持っとかなくちゃ」と買ったものもないではないが、「ローズ家の戦争」とか「エド・ウッド」とかもそうなのかと訊かれるとなぁ。それも違うような気がする。そうそう、一番最近買ったのは「チャイルド・プレイ:チャッキーの種」で、これは公開時に映画館で観ているのだが、ここまでのシリーズ全部をDVDで持ってる関係で「これは買っとかないと」だったのだ。な
    にしろあの殺人グッドガイ人形のチャッキーに二世ができるというハチャメチャな話で……。

     おっと、ハナシがちとあらぬ方向に逸れた。てなぐあいであれこれ考えてみた結果、ワタシがたどり着いた結論はなんつか「所有してなくてもそう苦労せずに手に入る、というか、観ることができるようになった」というあたりに落ち着いたのである。つまりは視聴できるTV局が増え、観たいものはどっかで放送してくれるぢゃないか、ということなんだが……。
    (以下次回 2008_07_26)                       

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

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

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

     こんにちは、高橋真人です。
     さて、前回までに完成させた「自前で作ったボタンコントロール」に、さらに拡張を施してみたいと思います。ただ、サブクラス化することで拡張するのでは前にやったのと同じで面白くありませんから、今度はAttachmentという仕組みを使ってやることにします。
     Attachmentというのは、簡単に言うと「既存のオブジェクトに動的に挙動などを付け加えたり外したりできる仕組み」です。オリジナルのPPをご存知の方ですとLAttachmentというクラスがあったのを覚えておいでかもしれませんが、考え方はあれと同じです。
     ただ、PPxにおけるAttachmentはCarbonイベントの仕組みの上に成り立っています。そのため、オリジナルのPPにおけるLAttachmentに比べるとクラス自体の実装は極めて簡素になっています。(LAttachmentほどのきめ細かい制御はできないように見えます。)
     Attachmentにおいて重要なのは、アタッチされる相手のオブジェクトであるPPx::Attachableが多くのクラスの継承元になっていることです。ですから、ほとんどのオブジェクトに対して、特にそのオブジェクト自体に手を加えることなく“動的に拡張を施せる”というところがポイントです。

     それでは早速コードです。例によって、以前のプロジェクトを複製しPPxForXcode10を作ってください。
     最初に既存のクラスに対する修正です。もちろん、MyView自体は変更しません。
     まずは、Application.cpです。先頭のヘッダファイルをincludeしている末尾に、

    #include "MyViewAttachment.h"

    と加えます。
     次にDoSpecificCommand()の中でViewを生成し終わったあと(view>SetFrameAdapter(adapter);のあと)に以下の4行を加えます。

    view->SetID(100);
    
    MyViewAttachment *attachment = new MyViewAttachment;
    attachment->Initialize(view);
    view->AddAttachment(attachment);
    


     次はMyWindowです。MyWindowはちょっとした新たな挙動を加えますので、ヘッダもソースも両方直します。まずはヘッダファイル(MyWindow.h)から。 include部の末尾に、

    #include 

    と加えます。次に、MyWindowの継承元にWindowDeactivatedDoerを追加します。よって、クラスの冒頭部は以下のようになります。

    class MyWindow :
       public PPx::Window,
       public PPx::SpecificMenuCommandDoer,
       public PPx::WindowDeactivatedDoer
    {
    ...
    


     あと、DoSpecificCommand()の次に(protected:部)、以下のメンバ関数宣言を追加します。

    virtual OSStatus DoWindowDeactivated(
                       PPx::SysCarbonEvent&    ioEvent,
                       WindowRef               inWindow);
    


     今度はソースファイル(MyWindow.cp)です。include部の末尾に以下を加えます。

    #include 
    #include "MyView.h"
    #include "MyViewAttachment.h"
    


     それから、ヘッダで宣言した新しいメンバ関数の実装です。

    OSStatus
    MyWindow::DoWindowDeactivated(
       PPx::SysCarbonEvent&    ioEvent,
       WindowRef               inWindow)
    {
    #pragma unused (ioEvent, inWindow)
    
       MyView *view = PPx::SafeDynamicCast(
                           GetContentView()->FindViewByID(100));
    
       MyViewAttachment *attachment =
           PPx::SafeDynamicCast(
           view->FindAttachmentByID(kMyViewAttachment));
       if (attachment) {
           view->RemoveAttachment(attachment);
           delete attachment;
       }
    
       return noErr;
    }
    


     それと、FinishInit()の末尾に新しいEventDoerクラスのInstallを忘れないように加えます。ちなみに、PPxでコーディングしているとついこのInstall部を書くのを忘れて「あれ、動かない。どうしてだ?」と悩むことが多いので、常にこれには注意しましょう。

    PPx::WindowDeactivatedDoer::Install(targetRef);

     それでは最後にアタッチメントクラスの全体です。少し長いですが一気に行きます。

    ====================== MyViewAttachment.h =========================
    #pragma once
    
    #include 
    #include 
    
    const UInt32 kMyViewAttachment = 'MVAt';
    
    class MyViewAttachment :
       public PPx::TargetAttachment,
       public PPx::ControlDrawDoer
    {
    public:
                       MyViewAttachment();
       virtual         ~MyViewAttachment();
    
       void            Initialize(PPx::EventTarget* inTarget);
    
    protected:
       virtual OSStatus DoControlDraw(
                           PPx::SysCarbonEvent&    ioEvent,
                           ControlRef              inControl,
                           ControlPartCode         inPartCode,
                           RgnHandle               inClipRgn,
                           CGContextRef            inContext);
    
    private:
       void                FinishInit();
       virtual CFStringRef ClassName() const;
    
       PPx::SysEventHandler    mEventHandler;
    };
    
    ====================== MyViewAttachment.cp =========================
    
    #include "MyViewAttachment.h"
    
    #include 
    #include 
    
    MyViewAttachment::MyViewAttachment()
    {
       SetID(kMyViewAttachment);
    }
    
    MyViewAttachment::~MyViewAttachment()
    {
    }
    
    void
    MyViewAttachment::Initialize(PPx::EventTarget* inTarget)
    {
       SetEventTarget(inTarget);
       FinishInit();
    }
    
    void
    MyViewAttachment::FinishInit()
    {
       EventTargetRef target = GetEventTarget()->GetSysEventTarget();
    
       if (target) {
           EventHandlerRef handler = PPx::ControlDrawDoer::Install(target);
    
           mEventHandler.Adopt(handler);
       }
    }
    
    CFStringRef
    MyViewAttachment::ClassName() const
    {
       return CFSTR("MyViewAttachment");
    }
    
    OSStatus
    MyViewAttachment::DoControlDraw(
       PPx::SysCarbonEvent&    ioEvent,
       ControlRef              inControl,
       ControlPartCode         inPartCode,
       RgnHandle               inClipRgn,
       CGContextRef            inContext)
    {
    #pragma unused (inPartCode, inClipRgn)
    
       OSStatus err = ioEvent.CallNextHandler();
    
       if (err == noErr) {
           PPx::CGContextSaver saver(inContext);
    
           HIRect frame;
           ::HIViewGetBounds(inControl, &frame);
           frame = ::CGRectInset(frame, -2, -2);
    
           float alpha = 0.5;
    
           if (::IsControlHilited(inControl) and
                   ::IsControlActive(inControl)) {
               alpha = 0.8;
           }
    
           ::CGContextSetRGBFillColor(inContext, 0.0, 0.0, 1.0, alpha);
           ::CGContextFillRect(inContext, frame);
       }
    
       return err;
    }
    


     以上です。以下は簡単な動作の説明です。
     新しいウインドウを開くとボタンがありますが、そのボタンには青い“覆い”がかぶさっています。クリックしてアラートを出すか、さらにウインドウを作るなどして、最初のウインドウがディアクティベートされる(アクティブでなくなる)と、青い覆いは消え去ります。

    ◇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=モサ伝]第306号

    2008-07-22 

    目次

    • WWDC初参加レポート
    • 「「Wonderful Server Life」    第74回   田畑 英和
    • 小池邦人のCarbon視点でCocoa探求
    • ターミナルの向こうから      第29回  海上 忍 

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

      〜「サーバ管理」編〜

     今回からLeopard Serverの「サーバ管理」について解説していきます。まず起動してすぐ分かるのがデザインが一新されたことです。ただし、1ウインドウの構成で、左側のリストでサーバやサービスを選択し、画面の右側でログ表示や設定を行うという大まかな構成はTiger Serverのころと基本的には同じですので、これまで「サーバ管理」を使った経験があれば操作方法はすぐに慣れるでしょう。

    ◇サーバの登録
     「サーバ管理」を起動してまず最初に行う操作はサーバの登録です。「サーバ管理」を起動するとサーバのアドレスと、サーバ上の管理者のユーザ名、パスワードを聞いてきますので、適切な値を入力すれば画面左側のリストにサーバを追加することができます。サーバは複数登録可能ですが、あとからサーバを追加するには画面左下の「+」メニューから「サーバを追加」を選択します。サーバの台数が多い場合はグループ化して管理したり検索条件を指定して、スマートグループを作成することもできます。
     また、左側のリストにはあらかじめ「使用可能なサーバ」という項目があります。ちょうどApple Remote Desktopのスキャナのようなもので、ここを利用すればネットワーク上のサーバを自動検出して登録することもできます。

    ◇サービスの選択
     サーバが登録できたら次は使用するサービスの選択を行います。画面左側のリストには各サーバごとにサービスの一覧を表示できます。1台のサーバだけを管理する場合はすべてのサービスが表示されたとしても特に問題はないかもしれませんが、Leopard Serverではサービスの数が増えていることもありサーバが複数台あった場合、すべてのサービスを表示してしまうとリストがかなり
    長くなってしまいます。
     そこでLeopard Serverの「サーバ管理」では、サーバごとにリストに表示するサービスが選択できるようになっています。サービスを選択するには、まず左側のリストで管理対象のサーバを選択し、ツールバーの「設定」をクリックしてから「サービス」画面を表示します。ここでどのサービスを左側のリストに表示するかを設定できます。例えばMac向けのファイルサービスを使用する
    のであれば「AFP」サービスを選択します。
     なおここでの設定はサービスの動作状況とは関係ありませんので、起動中のサービスであってもリストには非表示にすることもできます。設定が完了したら最後に画面右下の「保存」ボタンをクリックして設定を反映させます。

    ・サービスの選択(図はDNSサービスを選択しているところ)
    http://www.htabata.com/Site/Server/Pages/Leopard_Server_ch2.html#0

    ◇サービスの管理
     選択したサービスは左側のリストのサーバの下に表示されます。サービス名の左側に丸いアイコンがありますが、サービスが起動中の場合は緑色になりますので、起動中のサービスを一目で見分けることができます。
     サービスを起動するには、起動したいサービスを左側のリストから選択し、画面左下のボタンをクリックします。AFPサービスの場合は「AFPを開始」というボタンが表示されます。サービスが起動中にもう一度同じボタンをクリックするとサービスを停止できます。サービスの起動/停止ボタンはTiger Serverのころとは位置が違いますがこれも使っていればすぐに慣れるでしょう。サービスを再起動するのであれば「サーバ」メニューに再起動のための項目があります。

     AFPサービスであればデフォルトの設定でもすぐにサービスを開始できますが、まずはデフォルトの設定がどうなっているのかを確認しておくことも重要です。AFPサービスの設定を確認するには、左側のリストで「AFP」サービスを選択し、ツールバーの「設定」ボタンをクリックします。AFPの場合には「設定」のほかにも「概要」、「ログ」、「グラフ」、「接続」などの画面が用意
    されています。
     また設定画面はさらに細かく分かれており「一般」、「アクセス」、「ログ」、「アイドル状態のユーザ」の4つから構成されています。

    ・AFPサービスの設定画面
    http://www.htabata.com/Site/Server/Pages/Leopard_Server_ch5.html#17

     Tiger Serverのころは画面上のアイコンをドラッグ&ドロップすることで設定内容をファイルに保存することができましたが、Leopard Serverでは操作方法が変わりました。「サーバ」メニューの「書き出す」>「サービス設定…」から各サービスの設定内容をplist形式のファイルに書き出すことができます。ただしこの書き出し機能ではデフォルトの状態ではすべてのサービスの設定を書き出すようになっていますので注意が必要です。書き出し時にはどのサービスの設定を書き出すかを選択できるようになっています。

     それでは次回はAFPサービスの具体的な設定内容について解説する予定です。
    次回へつづく                             

    池邦人のCarbon視点でCocoa探求(2008/07/18)

    〜 ImageBrowser Viewを使う準備が大変 〜

    前回の例のように 、Imege Kitを利用すれば、割と簡単な記述のみで画像ファイルに対する高度な操作が実装できることが理解できます。今回からは、実際に「しんぶんし3」にIKImageBrowserViewクラスを実装していく作業に入ります。

    まず最初に行うべきことは、Interface Builderを使い、ドキュメント用nibファイル(今回はMyDocument.nib)のウィンドウオブジェクトに「ImageBrowser View」を配置する作業です。ところで、もし現在「Xcode 3.0 Developer Tools」を利用されているのなら、これに付属するInterface Builder 3.0には幾つものバグがありますので注意が必要です。特に、Carbon
    のnibファイルを編集する時には大きな問題が発生する事があります。現在「Xcode 3.1 Developer Tools」がADCメンバーサイトからダウンロードできますので、可能であるなら、それに付属しているInterface Builder 3.1の方を利用した方が安全だと思われます。

    「Xcode 3.1 Developer Tools」
    http://developer.apple.com/technology/xcode.html

    では、ImageBrowser Viewをドラッグ&ドロップでウィンドウ上へと配置してみます。ユーザインターフェースに用いる部品(コントロールやビューなど)は、Libraryウィンドウにまとめられています。その上部には、インターフェースの部品(プラグイン)をカテゴリーごとにまとめたグループが一覧されており、それを切り替えることで内容を表示できます。ImageBrowser View
    の居場所は、多くの部品が登録されている「Cocoa」の中ではなく「Image Kit」の方ですので注意してください。今のところ「Image Kit」から選択できるビューはImageBrowser View(IKImageBrowserView)と、前回その使い方を解説したImageView(IKImageView)の2種類のみです。

    さて、ImageBrowser Viewを、ド〜ンとウィンドウいっぱいに配置したいところなのですが、ちょっと待ってください。ドキュメントウィンドウのレイアウトを考えてみると、その右半分には、ImageBrowserで選択された画像を表示させるエリアが必要です。そして、将来的には、それと同じ場所に「対称処理をした画像」を表示させることになります。ですから、先んじて「Vertical Split View」(NSSplitView)を用意しておいて、その右側の「Custam View」
    と表示されているエリアにはImageViewを、左側のエリアの方にはImageBrowserを配置することにします。この作業により、どちらのビューもSplit Viewのサブビューとなります。

    この状態で、Split Viewの真ん中の柱(?)をつまんで左右に動かしてみると、それに連動して中の2つのビューは拡大&縮小(延び縮み)しません。中の2つのビューサイズが、スーパービュー(Split View)のサイズ変更と連動するように、Inspectorダイアログのサイズ設定(左から3番目の物差しアイコン)で調整する必要があります。真ん中に表示される「Autoresizing設定」の
    矢印とH表示を、すべてON(赤色)とします。この時、その右側で動いているアニメーションにより実際の挙動が確認できますが、中の赤色の矩形が外枠に追随するような動きであればOKです。ウィンドウとSplit View自身とのサイズ関係を保つのにも、上記とまったく同じ処置が必要ですので御注意ください。

    次は、ImageBrowser Viewの各アトリビュート(オプション)の設定です。こちらの作業はInspectorダイアログの一番左のアイコンで行います。まずImageBrowser Viewを一回クリックすると、そのスーパービューであるScroll Viewが選択されます。まずはこの状態で、アトリビュートの「Show Horizontal Scroll」のチェックが外れていることを確認してください。現状のImageBrowserでは、並べた画像の横スクロールはできませんので、このアトリビュートはONにしても意味がないのです。可能なのは縦スクロールだけですので、「Show Vertical Scroll」の方は、ちゃんとチェックが入っていることを確認してください。

    先ほどと同じ場所をもう一度クリックすると、今度はImageBrowser Viewの方が選択されます。現在選択されているビューの種類は、Inspectorダイアログのタイトルで確認できますので、間違えないようにしましょう。ここには、「Style」「Allows」「Display」「Zoom」といった幾つかのアトリビュートが用意されていますが、それぞれの詳細について後述したいと思います。例え
    ば、Styleの「Shadowed」「Outlined」「Titled」などのチェックボックスのON/OFFを試してみてください。ウィンドウ上でImageBrowserのテンポラリー表示がその設定の指示通りに変化することを確認することができます。

    続いて、File’s Owner(MyDocumentオブジェクト)と各種オブジェクトのコネクション(連結)を実現します。こちらの作業は、Inspectorダイアログの右から2番目の矢印アイコンで行います。ImageBrowserのOutletの「DataSource」と「delegate」をFile’s Ownerと連結します。こうした仕組みは、以前に解説したTable Viewとほとんど同じです。また、ソースコード側(MyDocument.h)には、以下の2つのインスタンス変数を定義しておき、それぞれにImageBrowser ViewとImageViewを連結させます。

    IBOutlet id    imageBrowser;
    IBOutlet id    imageView;
    


    最後に、ImageBrowserに表示させる画像サイズを変更するためのスライダーコントロールと、そこへの「画像登録」を実行するためのボタンコントロールを配置します。両コントロールには、それぞれzoomImage:とaddImage:というアクション・メソッドを割り付けておきます。この時、ソースコード(MyDocument.h)のクラス定義の方に、先んじて両メソッドを記述しておかないと、File’s Owner(MyDocumentオブジェクト)側に連結すべきアクションが表示されませんので注意してください。

    - (IBAction)zoomImage:(id)sender;
    - (IBAction)addImage:(id)sender;
    


    さて、ようやくnibファイル側での準備が終わりました。最近のMacプログラムではソースコードを記述するより、Interface Builderとの格闘の方が大変です。

    特にCocoaの場合、ここでの設定がソースコードと密接に関連していますので、より作業を複雑にしています。こんな調子では、実際のプログラミングに入る前にめげてしまう人も多いかもしれません? 次回こそは、本当にソースコードの話をしましょう(笑)。

    つづく

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

    〜 プレインテキストで文書作成(3)〜

     前回に続き、プレインテキストファイルをLaTeX文書に変換するコマンド「plain2」の使い方を紹介します。今回は、表と図のつくりかたを中心に解説します。

    ・JIS罫線の表
     plain2で枠線のある表を作成する場合、前回紹介したASCII記号(-、=、|、+)を使う方法のほかに、JISの罫線記号(─、┌、┣、┿など)を使う方法も利用できます。後述しますが、これはplain2の線画作成機能を利用したもので、要素間にスペースが多い印象の表になりますが、全角文字で統一できるため表をデザインしやすいという利点があります。サンプルはこちら
    http://www.mosa.gr.jp/wp-content/uploads/2008/07/jishyou.pdfを参照してください。

    - - - - -
    リスト1:JISの罫線記号を利用した表の記述例
    
    ┌────────────────┐
    │政令指定都市          │
    ┝━━━━┯━━━━━━━━━━━┥
    │北海道 │札幌市        │
    │宮城県 │仙台市        │
    │千葉県 │千葉市        │
    │埼玉県 │さいたま市      │
    │神奈川県│横浜市、川崎市    │
    └────┴───────────┘
    - - - - -
    


    ・線画を描く
     さて、次はplain2最大の大技ともいえる「線画」です。表1に示したJIS記号で図を描いておくと、LaTeXのpicture環境(線を用いた簡易作図機能)に置き換えてくれるという機能で、喩えるならば「アスキーアートをベクター画像に置換する機能」といったところでしょうか。文章では表現が難しい、抽象的な概念を伝えたいときに使うイラスト(絵解き)の作成や、地図のように線のみで表現可能な図を作成するときに力を発揮します。

    - - - - -
    表1:線画に利用できるJIS記号
    
    罫線    ─ │ ┌など
    矢印    ← → ↑ ↓
    斜線    / \ ×      
    点線    … :
    極太線  = ‖
    円柱    _  ̄
    - - - - -
    


     それでは論より証拠、こちらのPDF
    http://www.mosa.gr.jp/wp-content/uploads/2008/07/map.pdfをご覧ください。以下に示すリスト2を変換したもので、JIS罫線だけでそれなりの地図を描くことに成功しています。
     基本的には罫線記号を用いただけですが、ポイントが2つあります。1つは「縦/横線と斜線の接続」で、連続して(2つ以上)置かれた斜線の端が縦横線に接する場合斜線を曲げるという役割を果たします。もう1つは「丸みを持たせた角」で、縦線と横線が接する箇所(通常は┘や┌で表現する箇所)に斜線を用いることで、その部分をカーブさせることができます。

    - - - - -
    リスト2:JIS罫線で描いた地図
    
    ───────────
          R16
    ───\  ┌─────
         \ \
          \ \
          │ │
    ──────/ \──
    ──────\ /──
          │ │┌─┐
          │ ││◎│ ←ここ
          │ │└─┘
    - - - - -
    


     矢印を描く場合は、線の終端に矢印記号を使うだけです。斜線を矢印にする場合は、末端に「×」を置くようにします。なお、点線は「…」と「:」(全角のコロン)で表現できますが、JISの罫線記号では細線と太線の交差を示せないため、plain2では片側が終端となっている細線(”┌”や”┐”など)に太線/点線が隣接している場合には、細線についても隣接する線種で出力する仕様になっています。

    ・記憶装置を描く

     コンピュータ系の文書では、ハードディスクなどの磁気記憶装置を短い円柱で表現することが一般的です(由来は知りませんが)。plain2では、JIS罫線記号で描いた四角形の上辺/底辺を「_」と「 ̄」で表現することで、この円柱を描くことが可能です。完成イメージについては、こちら
    http://www.mosa.gr.jp/wp-content/uploads/2008/07/hdd.pdfを参照してください。

    - - - - -
    リスト3:ハードディスク風? の円柱
    
      ┌ ̄ ̄ ̄ ̄ ̄┐
      │     │  ┌ ̄ ̄ ̄┐ 
      │ HDD │  │   │
      │     │  └___┘
      └─────┘
    - - - - -
    


    ・ソースコードを表示する

     MOSA伝をお読みの方ならば、ソースコードを「ありのままの形」で文書に引用したいとお考えかもしれません。ワープロソフトではソースコードの雰囲気が出せない、インデントが妙だ、そもそもプロポーショナルフォントではダメだという場合には、plain2の「例示機能」が便利かもしれません。例示として出力すると、その範囲はLaTeXのverbatim環境(いわゆる「べた書き」)が適用され、英文フォントには等幅のTypeWriterが用いられるため、「ソースコードらしい」体裁となります。
     例示機能を使う場合は、行頭に「>>」(「::」も可)の2文字を加えるだけです。ただし、同じ書式が3行以上続かなければならず、インデントされていないことも条件になります。完成イメージについては、こちら
    http://www.mosa.gr.jp/wp-content/uploads/2008/07/source.pdfを参照してください。

    - - - - -
    リスト4:ソースコードを例示する その1(行頭が「>>」の場合)
    
    これは、CarbonSketchのソースコードの一部です。
    
    #include 
    #include 
    
    #include "CSkObjects.h"
    // also includes "CSkShapes.h"
    #include "CSkConstants.h"
    #include "CSkToolPalette.h"
    
    どうですか?
    - - - - -
    


    ★編集部注
    「>>」がメールの引用と表示されますので「::」の例を追加します。

    - - - - -
    リスト4:ソースコードを例示する その2(行頭が「::」の場合)
    
    これは、CarbonSketchのソースコードの一部です。
    
    :: #include 
    :: #include 
    ::
    :: #include "CSkObjects.h"
    :: // also includes "CSkShapes.h"
    :: #include "CSkConstants.h"
    :: #include "CSkToolPalette.h"
    
    どうですか?
    - - - - -
    

    ◇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=モサ伝]第305号

    2008-07-15

    目次

    • りんご味Ruby         第28回  藤本 尚邦
    • 藤本裕之のプログラミング夜話   #141
    • 高橋真人の「プログラミング指南」  第139回

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

    引き続き YahooHonyaku#open_top_page を実装します。前回は、ヤフー翻訳のトップページのHTMLを取得するための HTTP GET について、様々なレベルの手段を示しました。今回は、取得したHTMLをパースして、翻訳リクエストのためのフォームからパラメータ名などの情報を取得します。

    まず、YahooHonyaku#open_top_page のコードを示します。

     def open_top_page
       require 'open-uri'
       url = "http://honyaku.yahoo.co.jp/"
       http_header = {
         "User-Agent"     => "Mozilla/5.0",
         "Accept-Charset" => "UTF-8"
       }
       html = open(url, http_header) { |io| io.read }
       parse_form!(html)
       @top_page_opened = true
     end
    


    ヤフー翻訳は、HTTPヘッダーでUser-Agentを明示しないとちゃんと機能しないようなので、Accept-Charsetとともにopen-uriのopenメソッドに引数として渡します。(まだ実装も定義もしていない)parse_form!で、htmlをパースして翻訳リクエストのフォームからパラメタなどの情報を取得します。最後に、@top_page_opened に真偽値の true をセットします。

    ■ HTMLのパース

    HTMLをパースしてデータにアクセスする方法にも、HTTP GETの場合と同様、さまざまな手段が考えられます:

    ・正規表現を使ってやっつけでデータを取り出す
    ・HTMLをまじめにパースする
    ・既存のHTMLパーサを使う

    この中から、手軽でかつ確実な手段として、HTMLパーサのひとつであるHpricot を使って実装することにします(他の手段はたいへんなので省略します)。

    ◇ Hpricotの確認

    Hpricot は、Leopard に最初からインストールされています…と言い切りたいところなのですが、本当にそうだったかどうか忘れてしまいました。ターミナルで:

     

    $ ruby -r rubygems -e "require 'hpricot'"

    を実行して、エラーメッセージ(LoadError)が表示されなければ、すでにインストールされています。いずれにせよ

     

    $ sudo gem install hpricot

    を実行することにより、最新のhpricotをインストールまたはアップデートすることができます。

    ◇ parse_form! の実装

    parse_form! の実装は以下の通りです(注 – 要点を見やすくするためエラーの処理はいいかげんになっています):

     

    def parse_form!(html)
       require 'rubygems'
       require 'hpricot'
       doc = Hpricot(html)
       @form = doc.search("form[@name=textFormEntry]")[0]
       @key  = @form.search("input[@name=key]")[0]["value"]
       @time = @form.search("input[@name=time]")[0]["value"]
       if @form.nil? or @key.nil? or @time.nil? 
         raise "Yahoo翻訳の返すHTMLのパースに失敗しました"
       end
     end
    


    HpricotメソッドにHTML文字列を渡して呼ぶと、HTMLをパースして結果をHpricot::Docオブジェクトとして返します。Hpricot::Doc#search は、HTML構文木の中で、Xpath または CSS バターンにマッチする要素を検索します。textFormEntry という名前の form要素を探して、その中の2つのinput要素(それぞれの名前はkeyとtime)の値をインスタンス変数(それぞれ@keyと@time)に代入しています。これらのインスタンス変数の値は、翻訳リクエスト(HTTPPOST)を作るときのバラメータとして使います。

    Hpricot::Docオブジェクトには、searchを始めとしてドキュメント内の要素や属性などにアクセスするためのメソッドがいろいろと用意されています。Hpricotの使い方に興味のある方は、ドキュメントが:

     file:///usr/lib/ruby/gems/1.8/doc/hpricot-0.6/rdoc/index.html

    にインストールされているはずなので、この中のREADMEを読みながら、irbなどでサンプルコードを試してみると良いでしょう。

    ■ Mechanizeは?

    ところで、前回、Mechanize というライブラリがなんだか便利そうだぞ、試してみたい、というようなことを書きました。実際、今回の記事で紹介しようと思って試してみたのですが、衝撃的(?)な事実が発覚。なんと、今まで、ちまちまと作ってきた、あるいはこれから作るつもりの HTTPプロトコル・HTMLのパース・Webブラウザとしての振舞いのプログラミングのほとんどが、超お手軽にプログラムできてしまったのでした。

    このお手軽さ・便利さはとてもRuby的だと思うので、今すぐにでも紹介したいところなのですが、せっかくここまでYahooHonyakuの実装の説明を続けてきたのですから、Mechanize なしでとりあえず完成させてから紹介しようと思います。

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

     さて前回どこまで行ったかというと、ユーザ……というより話の流れからは「パソコン購買者」という呼び名のほうが正確だと思うが、は確かに増えたものの、その多くが「買ったままの状態」に満足し、新たにソフトを買い足すどころかバンドルソフトのバージョンアップもしてくれない。こりゃまたどういうわけだ、世の中間違っとるよぉ♪と思うかも知れないが実のところ間違って
    いたのはオレタチの方であったんである誠に遺憾に存じます、と……この辺でしたかね。

     もちろん異論もある。確かにビデオデッキの(あ、突然どうしてビデオデッキが出てきたんだ? と思った人は前回分を参照のこと)用途の主流は録画してテープを保存ぢゃなくて、レンタルビデオの再生だったかも知れんけど、CDとかはどーよ、買ってうちに貯めるんとちがうの? と思った人もいるのではないか。

     いやそーだと思うよね、現在約1,000枚の音楽CDの整理がつかず、まったくどうしていつの間にこんなに増えてしまったのかとため息をついているオレはその意見に深く激しく同意するモノであります。普通そうだよね? え、1,000枚が普通か? まぁ1,000枚は普通よかちと多めかもしれないけどさぁ。

     ところが先日、ワタシはそういう自分の常識というか依って立つ足場というか、が、ズズズズズリっと音を立てて動くようなパラダイムシフト的話を知ったのである。

     この前……6月の23日にアップルから、iTunes Store からの楽曲のダウンロードが全世界で累計50億曲を超えたというニュースが流れた。50億と言ったら50億である、アップルはこのうちどんだけが日本での売り上げなのか明らかにしてないが、まぁ1億や2億はありそうでしょ? となれば、デジタル音楽配信というさぞかし iTunes Storeが重きを占めている……と思うでしょ?
     
     ところが調べてみると驚愕の事実がわかるのだ。
    ここ(http://www.riaj.or.jp/release/2008/pr080221.html)に社団法人日本レコード協会が発表した2007年の有料音楽配信売上実績ちう表があるのだが、これによれば2007年に利用された有料音楽配信の総回数は464,996,000回……ざっと4億6千万回。で、そのうち iTunesを含むインターネットを通してのダウンロードはなんと、30,983,000回。1割に満たないのである。金額ベースでやっと7.8%である。

     残りの9割以上を占めている有料音楽配信とはなにか? ここでみのもんた風にもったいぶってもしょうがないので答えを書くとこれは「モバイル」なんである。つまりケータイに対してダウンロードされる着うた、着うたフルの類ですな。考えてみれば iPodがいくら売れているといっても携帯の比ではないわけで、パイがでかいんだから9割超が着うたなのも当然か、とも思ったのだが、これ、パイの大きさだけでわかったつもりになっていい話ではないのだ。

     オレと同じように不案内な人もいると思うので解説すると、着うたというのは iTunes Storeで売ってるような音楽デジタルデータの一部(サビの部分とか)をケータイの着信音として利用できるサービスで、1曲平均105円でダウンロードできるもの。これが iTunes Storeと同じまるまる1曲になったのが着うたフルなんだが、ビットレートが32Kbps〜48Kbps(iTunes Storeで売られてるのはm4pが128kbps、m4aなら256kbpsである)と低音質にも関わらず値段は1曲210円〜420円もする。

     まぁしかし値段は置こう、iTunes Storeで買うほうが音質も良くて安いとしても、前提となるパソコンやiPodはそれなりに高価だし(今度 iPhoneで可能になるだろうが)、ひょいと着信音にできるわけぢゃない。オレがパラダイムシフト的と言ったのは、こうして売れている着うたが「他のメディアに保存できない」ってことなのだ。つまりね、例えば420円で宇多田ヒカルの新曲を着
    うたとして買うでしょ? 他の曲を着うたにするときには(まぁ何曲かはストックできるようだが)基本的にそれは消しちゃうのである。

     オレ的な感覚だと「買ったものなんだからCDとかに焼いておき、将来好きなときにいつでも楽しめる」のが普通とか思うのだが、現実は違うのである。やぁびっくりしました。ケータイで宇多田の「Stay Gold」を着うたにしているお姉ちゃんはあれをほぼレンタルビデオ(2008年ではDVDですな)感覚で「消費」しているんだよ。ほんで、そういう感覚なんだとわかってみると、他のコトも見えてくるような気がするのである。 (以下次回 2008_07_12)
                          

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

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

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

     こんにちは、高橋真人です。
     朝のニュースワイドショー番組で、午前7時のSoftbankショップ表参道店からの生中継が、しかもほとんどのテレビ局で同時に行われるなどという、今までの私たちにはほとんど縁のなかった「メジャー」な世界での出来事に興奮し、戸惑い、何だか訳が分からなくなりそうな今日このごろですが、皆さんは元気にiPhoneプログラムを開発されておいででしょうか?
     私はと言えば、SDKの登録作業でひっかかり、わざわざUSにまで行ったにも関わらずWWDCの会場でも解決せず、結局、帰国後にデベロッパサポートとメールのやり取りやらFAX送信やらでようやく開通したものの、実機への転送作業に苦心惨憺の末成功したのが、ようやくiPhone 3G発売日の前日(涙)。
     とりあえずiPhoneアプリの構想はあるものの(今はアイデアが勝負ですから、どんなアプリかは発表するまでは内緒・笑)、販売に行き着くまでの手続きがまたかなりややこしいという噂を聞いて恐れおののいている状態です。
     「こんな時にPPxの連載なんかやっている場合かよ」というご批判の声があるのは重々承知ですが(笑)、実はiPhoneプログラムにも(無理矢理?)PPxを活用することはできるのではないかと踏んでいますので、批判もモノともせず(笑)、もう少し続けてまいります。

     さて、前回作成したプログラムには実は足りない部分がありました。この連載をしっかり読んでくださっている方は、こちらから言う出すまでもなくお気付きかもしれませんが。
     一つ前のプログラムでやった「ボタンがディスエーブルになった時の描画処理」がこのプログラムには欠けています。ウインドウを2つ以上開けば、いやでもどちらかのウインドウは後ろに回りますから、ボタンだけがアクティブなままだと、ちょっと浮いて見えてしまいます。
     それを防ぐためには、ディスエーブルになったときの見た目を自分自身で描画してやる必要があります。以前の、ボタンコントロールを流用してViewのビジュアルを得ていた時には、実はボタンコントロール自体が、自分がディスエーブルになったことを察知してちゃんとこの処理をやってくれていたのですが、自分ですべてをやる場合は、そこも自分で面倒を見てやる必要があります。
     本当は、前回のときにこの部分の実装も組み込んだ状態でご紹介したかったのですが、ボタンそのものに関してはすぐにできたものの、表示文字列をディスエーブル状態にする方法がなかなか見つからず、間に合いませんでした。
     では、早速コードをごらんいただきます。例によって、DoControlDraw()内のみの変更です。
    変更箇所は以下の2つです。

    ・ハイライト状態の判断部分に3行追加します。

    【旧】
    if (::IsControlHilited(inControl) and ::IsControlActive(inControl)) {
       buttonInfo.state = kThemeStatePressed;
    }
    
    【新】
    if (::IsControlHilited(inControl) and ::IsControlActive(inControl)) {
       buttonInfo.state = kThemeStatePressed;
    }
    else if (not ::IsControlActive(inControl)) {    // ここからの3行を追加
       buttonInfo.state = kThemeStateInactive;
    }
    
    


    ・HIThemeDrawTextBox()の直前に以下を挿入します。
    
    if (not ::IsControlActive(inControl)) {
       textInfo.state = kThemeStateInactive;
       RGBColor textColor;
       ::GetThemeTextColor(
           kThemeTextColorPushButtonInactive, 32, true, &textColor);
       ::CGContextSetRGBFillColor(
           inContext,
           (float)textColor.red / 65535,
           (float)textColor.green / 65535,
           (float)textColor.blue / 65535,
           1.0);
    }
    


     以上を変更して走らせてみてください。
     ウインドウが後ろに回った時に、ボタンの部分が”Button”というラベルも含めて薄く表示されるようになったことが分かると思います。
     前回から登場しているHIThemeTextInfoというもの自体、今回のように自分で独自の“見た目”を持ったViewやウインドウを作ることでもなければ、めったに関わることはない仕組みだと思いますが、単に表示を薄くするだけでも、今回ご覧いただいたように決して簡単ではありません。
     まあ、前回お話ししたアピアランスマネージャが、ユーザーサイドに大幅に自由を提供しようという設計方針だったために、いちいちシステムに対して「Pushボタンのアクティブでない時の描画色は何色?」と問い合わせをして色をもらい、それで自分で設定してから文字を描くという回りくどい手順になっているわけです。
     とかく、「Cocoaなら、ずっと簡単にできるのでは?」と思われる方はいらっしゃるのですが、内部的に行っていることには実はそんなに大きな違いはありません。あとは、「気軽に使えるがカスタマイズの自由度には妥協する」か、「カスタマイズは徹底的に自分の気の済むようにやりたいので、多少の複雑さは甘んじて受け入れる」かの選択になるのだと思います。
     どちらが正しいのか、という性質の問題ではなく、必要に応じてどちらの選択肢も選べるというのが、いいのだと思います。

    ◇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=モサ伝]第304号

    2008-07-08 

    目次

    • WWDC初参加レポート
    • 「「Wonderful Server Life」    第73回   田畑 英和
    • 小池邦人の『NDAとはいったい何ぞや?』
    • ターミナルの向こうから      第28回  海上 忍 

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

      〜「サーバ管理」編〜

     前回10.5.3のアップデートを紹介したばかりですが、もう次のアップデート10.5.4がリリースされました。10.5.3はサイズが大きかったこともあり、過去のアップデートを含む10.5.4のコンボアップデートは677MBもあります。アップデートの内容はディレクトリサービス関連の修正が行われているほか、クライアント版と同様のアップデートやセキュリティ関連のアップデートがおこなわれています。

    ・Mac OS X Server 10.5.4
    http://www.apple.com/jp/ftp-info/reference/macosxserver1054.html
    http://www.apple.com/jp/ftp-info/reference/macosxservercombo1054.html

    ◇サーバ管理
     さて、それでは今回から「サーバ管理」を使った各種サービスの管理について解説していきます。まずは、サーバの管理ツールについてまとめておきます。これまではLeopard Serverで新しく導入された標準/ワークグループ構成を中心に解説してきましたが、このとき使用していた管理ツールは「サーバ環境設定」です。「サーバ環境設定」は標準/ワークグループ構成の場合のみ使用可能で詳細構成の場合は使用できません。サーバ構成を詳細にした場合は、各種サービスの管理に「サーバ管理」を使うことになります。
     「サーバ環境設定」と「サーバ管理」の違いですが、「サーバ管理」のほうがより細かな設定ができ、サービスによっては「サーバ管理」でないと管理ができないものもあります。具体的には、次のサービスが「サーバ管理」でないと管理できません。

    ・「サーバ管理」でのみ管理可能なサービス
      DHCP、DNS、FTP、MySQL、NAT、NetBoot、NFS、Open Directory
      Podcastプロデューサー、QuickTime Streaming、RADIUS
      WebObjects、Xgrid、ソフトウェア・アップデート、プリント

     では、これらのサービスを利用する場合にはサーバ構成を詳細にしなければいけないかというと実はそうではありません。標準/ワークグループ構成の場合でも「サーバ管理」は使用できるのです。
     「サーバ管理」を起動して標準/ワークグループ構成のサーバに接続すると、ダイアログが表示され本当に「サーバ管理」を使用するかどうかを聞いてきます。このとき「サーバ管理」ではなく「サーバ環境設定」を起動することもできますし、そのまま「サーバ管理」を使用することもできます。またサーバ構成を詳細に変換することも可能です。ただしサーバ構成を詳細に変換してしま
    いますと、標準/ワークグループ構成には戻せなくなり「サーバ環境設定」での管理もできなくなりますので注意しましょう。
     とにかく標準/ワークグループ構成でも「サーバ管理」を使えば「サーバ環境設定」では管理できないサービスも管理できるようになるということです。また、「サーバ管理」と「サーバ環境設定」の両方から管理可能なサービスもありますが、混乱を避けるために「サーバ環境設定」から管理可能なサービスは「サーバ管理」では設定を変更しないほうがよいでしょう。そもそも「サー
    バ管理」で設定が必要なようであれば、サーバ構成を詳細にしてしまえばよいのです。
     またファイアウォールは扱いが異なります。ファイアウォールは「サーバ環境設定」と「サーバ管理」の両方から管理可能ですが、内部的な仕組みが異なります。ですのでファイアウォールもやはり片方の管理ツールのみを用いるのがよいでしょう。

    ◇ワークグループマネージャ
     「サーバ環境設定」ではユーザおよびグループのアカウント管理もできますが、「サーバ管理」はサービスの管理を行うツールですので、詳細構成でアカウント管理を行う場合は「ワークグループマネージャ」を使用します。ただし一部の機能は「サーバ管理」を使用します。「サーバ環境設定」のユーザ管理には、ユーザが利用可能なサービスを設定する「サービス」設定がありますが、これと同様の設定を行うには「サーバ管理」を使用します。
     さらに、標準/ワークグループ構成でも「サーバ管理」と同様に「ワークグループマネージャ」を使用することができます。

    ◇共有ポイントの設定
     Tiger Serverでは共有ポイントの設定に「ワークグループマネージャ」を用いていましたが、Leopard Serverでは「サーバ管理」を使うように変更されました。つまり「ワークグループマネージャ」はアカウント管理に特化した管理ツールになったということです。標準/ワークグループ構成の場合は「サーバ環境設定」でも共有ポイントの設定を行うことができます。
     またFinderの「情報をみる」からも共有ポイントのOn/Offが切換えられるようになりました。

     このように管理ツールにはそれぞれの役割があり、共有ポイントの設定のようにTiger Serverから一部になっている部分もあります。ですので、まずは各ツールの役割をしっかりと理解し、管理を行うときにどのツールを使えばよいかを把握しておく必要があります。
     今回は管理ツールの概要を解説しましたが、次回はAFPサービスを取り上げて具体的な「サーバ管理」の使い方をみていきたいと思います。
    次回へつづく                            

    小池邦人の『NDAとはいったい何ぞや?』(2008/07/04)

    NDAとは 【秘密保持契約】 (Non-Disclosure Agreement) という意味だそうな。つまり、ある特定の秘密が漏れると困る場合に、秘密を提供する側と受ける側の双方で結ぶ契約です。ただし、ウェブサイト上でのNDA締結においては、その内容は秘密を提供する側からの一方的な要求であり、受け手が「それイヤだから契約内容を変えてくれ!」と言うことは不可能な場合がほとんどです。ウェブ上の「これを守るかい?」の質問に対しては、通常は「はい」と「いいえ」のボタンしか選択肢がありません。先へ進みたいが、その手法や内容に対しては意義を唱えたい場合でも、対応手段が用意されていないのが普通です。そんな状況で、MacやiPhone関連のデベロッパーも、ことある毎にウェブ上でApple社側とNDA(英語表記)を結ぶ機会に遭遇します。

    ところで、英語表記のNDAですが、日本人のほとんどはその内容を読んでいないのではないでしょうか? つまり、長々と色々な事が書かれているようですが、誰もその内容を正確に知らないわけです。パッケージを開けたら自動的に締結される「ソフトウェア使用許諾契約」みたいなもんですね(笑)。私は法律の事は詳しくありませんが、素人考えとして、秘密を開示する側が不利にな
    らないよう、ありとあらゆる条項が詰め込まれているのでしょう。まあ、細かい点は理解していないとしても、NDAの目的が「知り得た技術内容を公の場(雑誌とかウェブサイトとか不特定多数の集会など)で公開してはいけない」ことぐらいは理解できています。その点に関してだけは常識と言う事で、良い子のデベロッパーはそれを守ろうと一生懸命努力するわけです。

    ここで、iPhone SDK β版の例を考えてみましょう。この開発用ソフトは、ADCオンライン会員(無料)以上であれば誰でもダウンロードできます。当然、ADC会員になる時やSDKのダウンロード時にNDAが結ばれます。ただし、メンバー認可の過程に何らかの選別や認証は存在しません(年齢制限だけ)。メールアドレスや住所を登録すれば誰でもなれるので、うちの奥さんでもOKで
    す。当然、iPhone SDK β版に対しても「使用許諾契約」は必要でしょう。しかし、ほとんど誰でもダウンロードできるソフトの使用許諾にNDA(技術情報の開示の禁止)を含める必要があるのか? という疑問が残ります。ADC会員以外に秘密を漏らさないため? それは変ですよね。だって、ADC会員には誰でもなれるわけですから、秘密を欲しい人は参加してダウンロードするだけで
    す。

    それでは、他に何か理由があるのでしょうか? 予想よりデキが悪いことがバレて騒がれたくない? それは情報開示側の問題でしょうね(笑)。それとも、マスコミに現状を湾曲して伝えられるのが嫌だから? そんな事は秘密事項でなくても良くあることです。逆に真実を隠した方が、不必要な憶測で事実を曲げられてしまう場合が多々あります。秘密にすることで、まだダウンロー
    ドしていない人の興味をあおり、ダウンロード数を伸ばすため? う〜ん、これは使えそうな作戦かもしれません(笑)。バレルことで秘密開示側が明らかな不利益を被る場合「秘密を得た特定の人」に対しNDAを結ぶという事は理解できるのですが、不特定多数の人が結ばなければいけないNDAの意味とはいったい何なのでしょうか?

    WWDCの場合もそうです。WWDCはADC会員なら誰でも参加できます。やはり認証や選別はありません(年齢制限のみ)。ところで、WWDCへ参加すれば、もれなくApple社の新製品情報を入手できるでしょうか? 「Snow Leopard」の販売開始日を知ることが可能でしょうか? iPhoneの出荷台数の各店舗への配分が分かり、販売日に入手するのに有利に働くでしょうか? そんな事はありません。今まで参加してきた私の個人的見解ですが 、外に漏れると「こりゃマズイな」と思うような情報開示は皆無なのです。事実、何年か前までのWWDCは、セッション内容に対してNDAはかかっていませんでした。では、何のためのNDAなのか? ライバルに最新テクノロジーの動向を知られたくないため? 冗談でしょ! WWDCにはマイクロソフト社員も数多く参加しており、セッション終了時に、Apple技術者に対しバリバリ質問を投げかけております(笑)。

    デベロッパー側はDNAで厳しく縛られるのですが、その傍らでシーディング(テストパイロット)ソフトの情報はすぐにウェブサイトに流れますし、「Snow Leopard」のスクリーンショット
    (http://www.engadget.com/tag/SnowLeopard/)等も堂々とアップされ、その詳細な内容を詳しく掲載しているサイト
    (http://www.roughlydrafted.com/2008/06/23/ten-big-new-features-in-mac-os-x-snow-leopard/)まであります。こういうサイトに対しApple社は、速やかに法的処置を取ると
    思いきや、多くは野放し状態です。また、 Apple社のディスカッションボードで、
    (http://discussions.apple.com/forum.jspa?forumID=727)iPhone SDKの技術的な内容が頻繁に話されていたりもします。こういう状況を見るにつけて「興味をアオルため、いくらか漏れることを計算してNDAを結ばせているのでは?」と勘ぐりたくなるのが正直なところです。

    そしてWWDC終了後、MOSAで「WWDC参加者情報交換会」(対象は参加者のみ)を開催しようと企画した時です。毎年「WWDC報告会」と称して似たようなイベントを開催していたのですが、その企画の一部を変更したわけです。すると、すかさずアップルからクレームが入りました。 アップル曰く「WWDC期間中会場内であれば参加者同士が情報を交換することは問題ございませんが、WWDCを離れますと、WWDCで得た情報を交換できるのは同じ会社の同じプロジェクトに携わっている方でADC Online以上にご登録の方同士に限られます。参加者同士であってもこれに当たらない場合は情報を交換することはできません」だそうです。つまりこの企画は、NDA違反にあたる可能性があるそうです。「WWDC参加者同士の情報交換」もダメだと言うわけです。

    ちょっと待ってください。 このアルゴリズムに準じれば、ツアーのホテルで同室になった参加者や、WWDCの帰りの飛行機で隣の席に座った参加者と仕事関連でWWDCがらみの話をするのも規約違反になります。それどころか、MOSA開催の現地パーティー(アップル関係者も参加)での情報交換も間違いなく規約違反です(笑)。Apple社は、デベロッパー1社から10人ぐらい参加していると思っているのでしょうか? うちはたった1人です(笑)。高い旅費と参加費を払い(MacBook Air上位機種が買える)WWDCへ参加し、どう考えても、あのセッション量を1人でこなすのは不可能ですから、参加者同士(みんな似たような環境)が集まり、聞けなかったセッションの情報や感想を交換して仕事に生かそうと言うのが企画の趣旨です。「鉄は熱いうちに打て」ですね。

    これは、ごく普通の考え方でしょう。 だいたい、我々の仕事とはMacやiPhone関連ですから、Apple社にとっても大きなメリットがあるわけです。もともと、WWDCとは、そうした目的のために開催されるカンファレンスでなわけで、これでは何のためのWWDCなのか? 誰のためのWWDCなのか? と言うことになってしまいます。 また、iPhone SDKは正規版になってもNDAが取れないという噂もあります。だとすると、iPhone開発関連の書籍や技術セミナー、加えて
    雑誌やウェブでの技術解説や議論などもすべてダメという事になります。iPhoneの場合、誰でもオープンにアプリケーションを開発できるのが素敵なわけですから、「やってみよう!」と思い立つ人達の間口を狭くするような愚行だけは止めていただきたいと思います。

    スティーブ、あなたの会社が世に出す製品は美しいです。ボタンもただひとつで操作も簡単、ユーザの才能や感性をうまく引き出します。しかし、あなたの会社が世に出すNDAは、まるで日本家電のリモコンのごとく、不必要な多くのボタンがユーザの才能や感性を阻害しています。
    以上                                 

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

    〜 プレインテキストで文書作成(2)〜

     前回は、プレインテキストファイルをLaTeX文書に変換するコマンド「plain2」のかんたんな紹介を行いました。今回は、plain2の少し高度な使い方を紹介します。

    ・前回の補足・訂正
     前回plain2のインストール方法について紹介したとき、plain2.hでのINTERNAL_CODEの定義を「CODE_EUC」から「CODE_SJIS」に変更するパッチを挙げましたが、文字コードをSJISに統一する場合、plain2の全ファイルに含まれる漢字コードをSJISに変換する必要があります。plain2のソースコードはEUCでエンコードされているため、INTERNAL_CODEの定義を変えただけでは、意図どおり変換できません。お手数ですが、plain2.hをオリジナルのものに差し替えたうえで、再コンパイル&インストールをお願いします。
     EUCエンコードされた文書をplain2で処理する場合は、次のようにオプション「-jis」を指定し、LaTeXソースをJISエンコードで出力します。Mac OS X用に配布されている日本語pTeXパッケージは、SJIS/JISエンコードのTeXファイルに対応するので、文字エンコード形式を変換せずそのままplatexコマンドでタイプセットできます。

    - - - - -
    $ plain2 -tex -jis source.txt > after.tex
    $ platex after.tex
    - - - - -
    


    ・タイトルを設ける
     plain2では、文書の先頭にタイトルを設けることができます。タイトルは「src/title.c」の定義に従い、予約語を持つ行をタイトル行として変換します。たとえば、リスト1の内容をplain2で変換し、platex → dvipdfmxの順でタイプセットを行うと、
    http://www.mosa.gr.jp/wp-content/uploads/2008/07/title.pdfのようなPDFが得られます。
     なお、タイトルは必ず先頭行に記述します。著者や日付は省略できますが、タイトル部分(リスト1でいえば1〜3行)に空白行を設けることはできません。タイトル部分と本文の間には、1行以上の空白を置く必要があります。書式に誤りがある場合には、ベタ書き(verbatim環境)として出力されます。

    - - - - -
    ○タイトルの予約語と書き方
    
    題名    題名、『』、「」
    日付    日付、XX年XX月XX日
    著者    著者、by
    連絡先  連絡先、TEL
    - - - - -
    


    - - - - -
    リスト1:タイトルの記述例
    
    1: 『最強:MOSA伝説』
    2: 著者  海上 忍
    3: 日付 2008年7月5日
    4: 
    5:  ここから本文。うんたらかんたら
    - - - - -
    


    ・項目型リスト
     スペースを除いた行頭にアスタリスク(半角/全角)、プラス(半角)、中黒(全角)、ダッシュ(半角/全角)いずれかの記号がある場合は、項目型リスト(LaTeXのitemize環境)として扱われます。最大で4段階のネストに対応するため、入れ子状に階層化された箇条書きの文書を作成するときに役立ちます。
     リスト2では、3段階にネストする形で項目型リストを記述しています。行頭の記号は、前述したものであれば区別なく使用できますが、半角記号の場合は直後に半角スペースを置かなければなりません。出力結果は、こちらのPDFhttp://www.mosa.gr.jp/wpcontent/uploads/2008/07/list.pdfをご参照ください。

    - - - - -
    リスト2:項目型リストの記述例
    
    ・関東地方
          ・東京都
          *神奈川県
                - 横浜市
                - 川崎市
          + 千葉県
    * 近畿地方
          - 大阪府
          ・京都府
    - - - - -
    


    ・列挙型リスト
     記号ではなく、行頭に数値やアルファベットを置く形で箇条書きを行う場合には「列挙型リスト」(LaTeXのenumerate環境)の手法を用います。スペースを除く行頭に、全角/半角のアラビア数字またはローマ数字、半角のアルファベットがある場合に、それらを順序番号として使用した列挙型リストが出力されます。なお、ネストのレベルは項目型リスト同様、最大で4段階です。出力結果は、こちら
    http://www.mosa.gr.jp/wp-content/uploads/2008/07/enum.pdfをご参照ください。
     なお、順序番号の直後には、半角ドットまたはカッコ(半角/全角)の修飾記号が必要です。修飾記号とリストにしたい文字列の間には、半角スペースを置きます。

    - - - - -
    リスト3:列挙型リストの記述例
    
    1. Mac OS X
      a) Tiger
      b) Leopard
    2. Linux
      i. SuSE
      ii. RedHat
    - - - - -
    


    ・表の作成
     plain2では、かんたんな方法で表(LaTeXのtabular環境)を作成できます。使用する記号は横線が「-」と「=」、縦線が「|」、線の交差する箇所が「+」、これだけです。論より証拠、リスト4と出力結果
    http://www.mosa.gr.jp/wp-content/uploads/2008/07/hyou.pdfを見比べてください。なお、表が正しく解釈されるためには、罫線を含め3行以上の表サイズが必要です。
     右/左寄せを行う場合は、同じカラムに属すフィールドを統一させます。全フィールドについて処理を行わなくても、半分以上のフィールドが右/左寄せされていれば、そのカラムは多数派に従った書式が適用されます。

    - - - - -
    リスト4:表の記述例
    
    +-----------------------------+
    |政令指定都市                  |
    +=======+=====================+
    |北海道  | 札幌市               |
    |宮城県  | 仙台市               |
    |千葉県  | 千葉市               |
    |埼玉県  | さいたま市           |
    |神奈川県| 横浜市、川崎市       |
    +-----------------------------+
    - - - - -
    

    ◇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=モサ伝]第303号

    2008-07-01

    目次

    • りんご味Ruby         第27回  藤本 尚邦
    • 藤本裕之のプログラミング夜話   #140
    • 高橋真人の「プログラミング指南」  第138回

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

    今回は YahooHonyaku#open_top_page を実装します。

    open_top_page は、第25回で書いた手順のうち「WebブラウザでYahoo!翻訳のページを開く」に相当します、以下のような手順:

     ・HTTPのGETメソッドでYahoo!翻訳のトップページを取得
     ・結果のHTMLをパースして必要な情報を取り出す
     ・成功したら、@top_page_opened に true をセットする
    


    になります。

    ■ Ruby で HTTP GET するには

    ◇ その1 — 低レベルな方法 (socketをたたく)

    Rubyで、HTTPプロトコルを扱う方法はいろいろ考えられます。もっとも原始的な方法は、TCPSocketを使って自分でHTTPプロトコルの通信をプログラミングすることでしょう。Yahoo!翻訳のトップページをHTTPでGETする場合は以下のようになります:

     require 'socket'
     response = TCPSocket.open("honyaku.yahoo.co.jp", 80) { |io|
       io.write "GET / HTTP/1.1\r\n"
       io.write "Host: honyaku.yahoo.co.jp\r\n"
       io.write "User-Agent: Mozilla/5.0\r\n"
       io.write "Accept-Charset: UTF-8\r\n"
       io.write "\r\n"
       io.read
     }
     html = response.split("\r\n\r\n")[1..-1].join  # http body を取り出す

    【編集部注:\r\n部分の『円記号』は『バックスラッシュ』に置き換えてください。以下も同様です】

    TCPSocketクラスはファイルなどの入出力を扱うIOクラスの派生クラスです。io.write で HTTPリクエストを送信して、io.read でHTTPレスポンスを受信しています。response はサーバから受信した生データ(バイト列)ですから、最後の行では、(安直な方法で)HTTPレスポンスのボディ部分にあるHTMLを取り出しています。

    ・生バイト列を「連続した改行」で分割し配列を作る — split(“\r\n\r\n”)
    ・配列の最初の要素(HTTPヘッダ部)を取り除く       – [1..-1]
    ・配列の残りの部分をつなげるとそれがHTTPボディ   – join

    (効率的にも、HTTPプロトコルの扱い方としても、最終的な実装としてはおすすめできませんが、まずは、とりあえず動くものを手軽に実装ということならばこういうのもありでしょう)

    ◇ その2 — 高レベルな方法 (net/http を使う)

    上のようにTCPSocketの使い方自体は簡単ですが、HTTPプロトコルの面倒は自分で見なければなりませんでした。そこで、HTTPなどよく使われるプロトコルにはあらかじめライブラリが用意されています。/usr/lib/ruby/1.8/net の中を見ると、どんなプロトコルのライブラリがあるか見ることができます。HTTPについてはnet/http があります。以下はnet/httpの使用例です:

     require 'net/http'
     html = Net::HTTP.start("honyaku.yahoo.co.jp") { |http|
       response = http.get("/", "User-Agent"     => "Mozilla/5.0",
                                "Accept-Charset" => "UTF-8")
       if response.is_a? Net::HTTPSuccess
         response.body
       else
         raise "エラー発生!!"
       end
     } 
    


    もちろん、この response は生データではなく、Net::HTTPResponseクラスのオブジェクトとして構造化されていますから、リターンコードやボディ部などへのアクセスは簡単にできます。

    ◇ その3 — もっと高レベルな方法 (open-uri を使う)

    net/httpではHTTPプロトコルの細かい機能をいろいろと使い込むことができますが、WebサイトのトップページのHTMLをGETするだけというような単純な用途にはおおげさすぎます。そういうときには open-uri を使います。

     require 'open-uri'
     html = open("http://honyaku.yahoo.co.jp/",
                 "User-Agent"     => "Mozilla/5.0",
                 "Accept-Charset" => "UTF-8") { |io| io.read }
    


    これでだいぶすっきりとしました。以上で、Yahoo!翻訳トップページのHTMLを取得することができるようになりました。

    ■ おまけ — 日本Ruby会議2008

    6月20日(金)から22日(日)にかけて、つくば国際会議場で、日本Ruby会議2008が開催されました。立派な会議場で海外からの発表者も多く、Rubyに関して古代人(Rubyについての最初の本「オブジェクト指向スクリプト言語Ruby」出版以前からの人は古代人だそうです)の私には「ミカン箱の上で歌ってるときから応援してたアイドルが武道館でライブ」のような感慨深いものがあります。

    Ruby会議で私が気に入っているものの一つに、発表中サブスクリーンに表示される IRC チャットがあります。とりわけ、海外の発表者のセッションのときには、逐一翻訳してくれるので、英語聞き取りが苦手な私にはとてもありがたいです。日本人の質問者が、(無理して)英語で質問しようとしてしどろもどろになると「日本語でおk」と突っ込まれ、さらに母国語がフランス語の発表者が英語で答えようとしてしどろもどろになると「フランス語でおK」と突っ込まれる、といったお約束を楽しみつつ、発表に関する解説があったりして素晴らしい。

    Macに関しては、Laurent Sansonettiさん(Apple)による「RubyとMac OS Xの未来」という発表で、MacRubyを中心にした話がありました。MacRubyが目指すスローガンは:

     Rubyを使う楽しみのためにパフォーマンスを犠牲にすることなく、成熟した Mac OS Xアプリケーションの作成を可能にする

    で、高速化やスレッド安全性などが重視されています。「AppleはRubyによるMac OS X開発をサポートし推奨する(Apple supports and encourages Mac OS Xdevelopment using Ruby)」とのことです。これも楽しみですね。

    ◇ [補足] MacRubyのインストール方法(例)

     $ svn co http://svn.macosforge.org/repository/ruby/MacRuby/trunk \
              /tmp/macruby
     $ cd /tmp/macruby
     $ rake
     $ sudo rake install
    


    これで、/Library/Frameworks/MacRuby.framework および /usr/local 以下にインストールされます。MacRubyは、既存のRubyやRubyCocoaから完全に独立していて、それらを破壊することはありません(そのはずです)。なお、開発中につき、ビルドできなかったり動作しなかったりということはあるかもしれません。

    次回は、HTMLをパースして翻訳リクエストのパラメータ名などの情報を取得します。今回のRuby会議で存在を知ったMechanizeというライブラリが、この目的に合うかもしれないので、試してみようかと考えてます。

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

     WWDCのために時間が開いてしまったが、話がどこまで行ったか覚えてますか? そう、パソコンを買うとバンドルソフトというものがたくさん付属してくるようになり、ほとんどのユーザはバンドル品以外のソフトをわざわざ購入しなくなる。早い話ワープロならワープロ、辞書なら辞書、一つの分野で一つの製品がバンドル品に選ばれてしまうと競合品が生き残るのはとっても難しい状況……なんてんですか、1匹の精子が受精すると他の何億が即座に御陀仏てな「やけっぱちのマリア」的というか、そんな話になったわけ。

     この状況下でソフト屋が生き残るミチは2つ。競合製品のいない独自分野のソフトを生み出すか、それとも競合製品に勝ってバンドルの座を勝ち取るか。前者は聞けば格好いいけど早い話それは冒険なわけだし、既になんらかの製品をもってるのであれば当然後者を目指す。前回見たようにバンドルソフトには「おまけ商品と見なされてしまう」というデメリットも確かにあるのだが、それでも知名度が上がることはいいことだし、流通を通さずにユーザから直接支払いを受けられるバージョンアップは美味しいし、と。

     ところがあのバブル弾けて10年、2000年問題を乗り越えてやってきた21世紀はそんな甘い時代ではなかったのである。……って実のところ、そういう時代が来てしまえば誰が見ても当たり前のような気がしたんだけどね。要するにインターネット・ブームに乗って増加したパソコンユーザってのは、かつてビル・ゲイツが夢想したように「一家に一台、家電のようにパソコンを買って」
    くれたけど、その使い方も「家電のよう」だったのだ。こっちはさすがのビル・ゲイツでも予想外(たぶん)、世界最高のビジネスマンでさえ予想しないことをオレたちシモジモのプログラマ風情が予想できるはずもなかった。

     え? 「パソコンの使い方が家電のよう」ってどういうことだって? わかりませんか? つまり冷蔵庫や洗濯機、電子レンジと同じ、普通のヒトは一度買ったら、壊れでもしない限りもうその機械に金をかけたりしないのである。……例えば冷蔵庫の目的はモノを冷やすことだ。したがってユーザは冷蔵庫が冷えてる限り不満はない。洗濯機の仕事は洗うこと、そりゃ「こっちの方がよ
    く落ちる」とか「これを使えば森の香り」とか言われれば洗剤や柔軟剤は変える。でも洗剤や柔軟剤は誰がどう見ても消耗品だからね。電子レンジにしてもそうでしょ? そういうものと比べるからいけない? もっとパソコンに似た使われ方をするものがあるだろって?

     21世紀初頭、すなわち2001年(21世紀は2001年から、2000年からだと思ってませんでした?)の日本における一般的家庭において、おそらくパソコンとその使用形態が最も似通った家電はビデオデッキであったと思う(DVDプレイヤーぢゃないのか、と言うかも知れぬが、社団法人 日本映像ソフト協会の資料によればDVD再生機器の推定普及率は2002年で35%なので、その2年前であれば圧倒的にビデオデッキを使っている家庭の方が多かったはず)。そこで考えて欲しいのだが、普通の家庭におけるビデオデッキ関連の支出で最も多いのはどんな項目だろうか? 生テープを買う? 違うよ、ビデオのレンタル料金である。

     どういうわけか我々の業界のニンゲンにはあのビデオデッキという機械を「何かを録画してとっておく機械」と認識しているヒトが多いのだが、普通の家庭ではあれは概ね「映画を借りてきて観るため」の機械だったのだ。そりゃたまには外出のために観られない番組を録画してあとで観たりするために生テープも買うさ。でも一度観たら消してまた他のを録画するために使う。ナニを言いたいかというと、こないだついに死刑になったミヤザキツトムみたいにアニメだのなんだの録画して部屋いっぱいに貯め込んでいるってヒトは、昔もイマも……いかにあんたの周りに多かろうと、世間一般を分母としたら圧倒的少数派なのである。

     パソコンもこれと同じ事情なんでね、こいつをメシの種として、四六時中その前に座っている我々は、なんとなく「パソコンがもっと普及したらすべてのユーザが我々と同じようなパソコンの使い方をするに違いない」という幻想を持っていたのだ。別に現状に不満がなくても新しいOSやソフトが出ればバージョンアップし、お金を使ってくれるというような、ね。でもそれは大間違い
    だった。彼らはバンドルソフトをおまけ商品と認識した上に、そのおまけ商品以上のものを欲しがらなかったのである。
                           (以下次回 2008_06_26)

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

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

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

     こんにちは、高橋真人です。
     今年もWWDCに参加してきました。時代の流れとは言え、ついに今年はCarbonの名の付くセッションが一つもありませんでした。あのアドビ社ですら、Mac用アプリケーションのCocoaへのポーティングを開始した今、もはやCarbonにこだわっている場合ではないのかもしれません。
     まあ、私としてもCarbonに固執しているわけでもありません(最近、Carbonで書くアプリケーションはこの連載用のプログラムだけになってしまいました・笑)ので、PowerPlant Xの連載にもそろそろ見切りを付けようかな、と思い始めています。
     ともあれ、やりかけた話には決着を付けねばなりません。いよいよ、HIViewのカスタマイズのハイライト(というほど凝ったことはしていませんが)ということで、今までやってきたシステムが提供するPushButtonコントロールをそのまま利用するのではなく、表示部分や内部動作などを自前で実装する形にしてみたいと思います。(もちろん、OSの力を借りながら、ですが)
     では早速、プロジェクトの準備から。前のプロジェクトを複製してPPxForXcode09を作ってください。そして、MyView.cpの描画部の実装コードを以下に置き換えます。

    OSStatus
    MyView::DoControlDraw(
       PPx::SysCarbonEvent&    ioEvent,
       ControlRef              inControl,
       ControlPartCode         inPartCode,
       RgnHandle               inClipRgn,
       CGContextRef            inContext)
    {
    #pragma unused (ioEvent, inPartCode, inClipRgn)
    
       HIRect frame;
       GetLocalFrame(frame);
    
       HIThemeButtonDrawInfo buttonInfo = {
           0, kThemeStateActive, kThemePushButtonNormal,
           kThemeButtonOn, kThemeAdornmentNoShadow 
       };
    
       if (::IsControlHilited(inControl) and ::IsControlActive(inControl)) {
           buttonInfo.state = kThemeStatePressed;
       }
    
       HIRect labelRect;
       HIThemeDrawButton(
           &frame, &buttonInfo, inContext,
           kHIThemeOrientationNormal, &labelRect);
    
       HIThemeTextInfo textInfo = {
           0, kThemeStateActive, kThemePushButtonFont,
           kHIThemeTextHorizontalFlushCenter,
           kHIThemeTextVerticalFlushCenter, kHIThemeTextBoxOptionNone,
           kHIThemeTextTruncationMiddle, 1, true
       };
    
       HIThemeDrawTextBox(
           CFSTR("Button"), &labelRect, &textInfo,
           inContext, kHIThemeOrientationNormal);
    
       return noErr;
    }
    


     モサ伝の制限上、横の文字数が限られるために行数が多くなってしまっていますが、空白行を除けば10行余りのコードです。
     ただ今回のコードは、ある程度Carbonで凝ったアプリケーションを書いた経験のある人でないと見慣れないものばかりかもしれません。特に目立つのは”HITheme…”という識別子です。これは、昔懐かしい(?)アピアランスマネージャの流れを汲む仕組みに属するものです。
     アピアランスマネージャと言われてもピンと来ない人も最近はいるかもしれませんので、少し説明します。かつてまだMac OS 8も出ていないころ、OSが標準で提供するUIパーツは今のものに比べずっとシンプルでした。開発者がもっと多彩なUIを作りたいと思うと、OSが使用している仕組みを流用するなどということもできず、それこそ一から実装をする必要があったために、かなりの作業量を要したのです。
     新世代のOSを模索していたアップルが、そういう状況を解決しようとして出てきたのがアピアランスマネージャ、そして“テーマ”という考え方です。例えば“選択”を行った時に、その選択されているという状態をどのように表現するかということを考えてみます。
     今のMac OSでは、選択状態を表す色はデフォルトでは水色になっています。では、自分で独自のUIパーツを作った時に選択色を水色にすればいいのかというとそうではないわけです。何故なら、この“水色”をユーザーが変えることができるようになっているからです。
     システム環境設定のアピアランスというところを選ぶと、「強調表示色」というポップアップボタンが見えると思います。試しにこれを変えてみると、その後、テキスト選択やリスト選択などはすべて新しい色で描かれることが分かるはずです。
     このように、例えば選択色を描く際に“水色”と決め打ちをするのではなく、システムに対して「テキストの選択状態を示す色は?」などと逐一問い合わせをして、その色で然るべき部分を描くのがアピアランスマネージャの仕組みに乗っ取ったやり方です。
     ただ、前述の「強調表示色」の変更だけでは、メニューなどのハイライト表示などは変わりません。一応、アピアランスのシステム環境設定には名も「アピアランス」というポップアップがあり、ここをデフォルトの「ブルー」から「グラファイト」に切り替えることでメニューなどの色を変えることはできるのですが…
     実は、かつてアピアランスマネージャが登場したころ、アピアランスのテーマには”High Tech”と”Gizmo”という名の派手なテーマも存在していました。特に”Gizmo”の方は見た目がカラフルで、操作をするといろいろなギミック音を発するという凝ったものでした。
     当初は、さらにデベロッパによって様々なテーマが作られて、ユーザーがそれらを好き勝手に選んで使えるといった構想もあったのですが、一時フリーウエアでいくつかのテーマもあったものの、今ではそういった考え方自体が衰退してしまったように見えます。
     HITheme…の先頭のHIは、「ヒューマン・インターフェース」の略ですが、これはCarbonの技術のカテゴリーということになっているため、いずれはこのテーマという発想自体もなくなってしまうのかもしれません。

     とりあえず、プログラムを走らせてみれば動きは確認できるでしょう。コードの中身に関しては、Carbonフレームワークの奥深くにしまわれているAppearance.hとHITheme.hというヘッダファイルをご覧になれば、理解できると思います。

    ◇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.