MOSA Multi-OS Software Artists

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

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

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

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

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

    2007-12-25

    目次

    • りんご味Ruby         第16回  藤本 尚邦
    • 藤本裕之のプログラミング夜話   #129
    • 高橋真人の「プログラミング指南」  第127回
    • 開発ツールよもやま話      Xcodeのコード補完

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

    最近、1万個弱のHTMLファイルの中のscriptタグで埋め込まれたJavaScriptプログラムのバグをまとめて修正するという作業をしました。このときに初めて使ったHpricotがなかなか便利。ということで、今回はHTMLパーサライブラリのHpricotについて紹介しようと思います。

    この修正作業には、おおよそ以下のようなRubyプログラムを書いて一気に書き換えました。

     require 'rubygems'
     require 'hpricot'
     require 'fileutils'
     Dir["#{HTML_DIR}/**/*.html"].each do |path|
       modified = false
       hdoc = Hpricot(File.read(path))
       hdoc.search("script").each do |script_elem|
         if has_bug?(script_elem.inner_html)
           script_elem.inner_html = fix_bug(script_elem.inner_html)
           modified = true
         end
       end
       if modified
         FileUtils.mv(path, "#{path}.backup")
         open(path,"w"){|f| f.write(hdoc.to_original_html) }
       end
     end
    


    このプログラムの手順を日本語で書き下すと:

    ・HTML_DIR以下のすべてのHTMLファイルについて:
     ・Hpricotでパース
     ・全てのscript要素を検索
     ・各script要素について:
       ・inner_htmlにバグがあれば
        ・修正して書き換える
     ・バグ修正した場合:
       ・オリジナルをバックアップ
       ・ファイルを更新

    となります。(余談 – この種の書き捨てプログラムの実行は取り返しがつかないことにならないようデータのバックアップをとって慎重にやらなくてはいけませんね。LeopardならTime Machineの使いどころでしょうか?)

    上のプログラムで、Hpricotがどのように使われているかに着目してみましょう。
    まず

     

    require 'rubygems'
     require 'hpricot'
    


    でHpricotをロードしています。LeopardにはデフォルトでHpricotがインストールされています。次に

     hdoc = Hpricot(File.read(path))

    で、HTMLを読み込んでHpricotでパースして、結果のオブジェクトにhdocという名前を付けました。

     

    hdoc.search("script").each do |script_elem|
       ...
     end
    


    では、HTMLドキュメントの中のすべてのscript要素を検索して、それぞれについて処理をするループを構成しています。ループの中では、各script要素について:

     script_elem.inner_html

    で、script要素のinner_htmlを取り出します。バグがあれば修正して

     

    script_elem.inner_html = 修正したHTML片

    のように、script要素のinner_htmlを修正後の内容に書き換えます。script要素のループから抜けたとき、バグ修正が発生していた場合は、修正後のHTMLデータ

     hdoc.to_original_html

    をファイルに書き出します。to_original_html メソッドは、リファレンスマニュアルによると、*修正したところ以外は*もとのHTML文字列を返すメソッドです。完全なオリジナルのHTMLを返すわけではないのですね。

    以上のような感じでHpricotを使い、シンプルに目的の作業を実行するプログラムを書くことができました。

    上のプログラム例はそのままでは試すことができないので、そのかわり、実際に動かせる例として、Googleを検索して、Hpricotを使って検索結果からタイトルとリンクだけを抽出するRubyプログラム(コマンド)を書いてみました。

    ------------------------------------------- google.rb --
    #!/usr/bin/ruby -Ku
    class String
     require 'nkf'
     def u8() NKF.nkf("-w", self) end
    end
    
    class Google
     require 'rubygems'
     require 'hpricot'
     require 'open-uri'
     require 'cgi'
    
     URL_FORM = "http://www.google.com/search?q=%s&hl=ja"
    
     def self.search(*keywords)
       keywords = keywords.map{ |kw| CGI.escape(kw) }.join('+')
       url = format(URL_FORM, keywords)
       hdoc = open(url) { |io| Hpricot(io) }
       hdoc.search("div.g").map { |elm| new(elm) }
     end
    
     def initialize(element) @element = element end
     def title() @element.search("h2")[0].inner_text.u8 end
     def link()  @element.search("h2/a")[0].attributes["href"] end
    end
    
    Google.search(*ARGV).each do |i|
     puts i.title
     puts i.link
     puts
    end
    -------------------------------------------
    


    このプログラムをgoogle.rbという名前で保存し、ターミナルで

     $ ruby google.rb macbook ssd
     $ ruby google.rb 初音ミク ニコニコ動画
    


    のように検索語を並べて実行すると、上位数件の検索結果のタイトルとURLが空行区切りで出力されます。出力の加工やパースの工夫次第でおもしろい使い方ができそうですね。

    Hpricot作者のwhy the lucky stiffさんはHpricotの他にもいろんなプログラムを発表しています。私は2006年のRails Conferenceに参加したとき、whyさんと会ったことがあるのですが、夜の部では、ビデオ・アニメ・楽器などを駆使したひとくせあるライブパフォーマンスを行うなど、まさにアーティストというような活躍をされていました。きさくで陽気でとても楽しい方です。

    Hpricot
    http://code.whytheluckystiff.net/hpricot

    Hpricotのリファレンスマニュアル
    file:///usr/lib/ruby/gems/1.8/doc/hpricot-0.6/rdoc/index.html

    why the lucky stiff さんのソフトウェア作品
    http://code.whytheluckystiff.net/

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

     回を重ねてこの連載も129回……ちとキリは悪いが(128の方がキリがいい,よな?)、今回を「第三部:青春群像編」……ぢゃなかった「ツールバー編」の締めくくりとしたい。話題はツールバーの「表示モード」と「サイズモード」である。

     前回までで我々が(実はオレがだけど)作ってきたテストプログラムが表示するツールバーは、それぞれのアイテムのアイコン(ポップアップボタンもあるけど)の下にそれぞれラベルとして設定した文字列が表示されている。このアプリに限らず、たとえばこの原稿を書いているJeditのツールバーもそう、Finderのウインドウもそうだ。
     このツールバーを隠すには、前にやったようにウインドウの右肩部分にあるツールバースイッチをクリックすればいい。で、これをコマンドキーと共にクリックすると表示モード、サイズモードを切り替えることができる。知らなかった人はやってみてくだされ。

     ツールバーの表示モード、並びにサイズモードは、NSToolbar.hに以下のように定義されている。

    typedef enum {
      NSToolbarDisplayModeDefault,
      NSToolbarDisplayModeIconAndLabel,
      NSToolbarDisplayModeIconOnly,
      NSToolbarDisplayModeLabelOnly
    } NSToolbarDisplayMode;
    
    typedef enum {
      NSToolbarSizeModeDefault,
      NSToolbarSizeModeRegular,
      NSToolbarSizeModeSmall
    } NSToolbarSizeMode;
    


     個々の説明は必要ないよね。で「コマンドキー押しながらツールバースイッチをクリック」でこれらが以下の順番で変わるわけだ。

     

    最初:NSToolbarDisplayModeIconAndLabel で NSToolbarSizeModeRegular
     1回:NSToolbarDisplayModeIconAndLabel で NSToolbarSizeModeSmall
     2回:NSToolbarDisplayModeIconOnly で NSToolbarSizeModeRegular
     3回:NSToolbarDisplayModeIconOnly で NSToolbarSizeModeSmall
     4回:NSToolbarDisplayModeLabelOnly で NSToolbarSizeModeRegular
     5回:NSToolbarDisplayModeLabelOnly で NSToolbarSizeModeSmall
     6回:最初に戻る。
    


     もしアプリケーションの起動時、あるいは特定のウインドウを開くときに、これらのモードを特定のものにしたければ、NSToolbarのオブジェクトに対してsetDisplayMode: とsetSizeMode:で好きなものを設定する。それをしなければこれらの初期値は「NSToolbarDisplayModeDefault」と「NSToolbarSizeModeDefault」であり、これらは前回アプリケーションが終了したときの値(最初に起動されたときは上にあるようにNSToolbarDisplayModeIconAndLabel で NSToolbarSizeModeRegular)になる。
    「~/Libraries/Preferences」にある初期設定ファイルを開くと「NSToolbarConfiguration_MOSA_SAMPLE」というキーで参照できるDictionaryとして保存されているのでご確認を。

     ここまでの解説に使ったテストプログラムはソース、nibファイルなど一そろいにしてMOSAのサイトに公開してもらうので、興味や疑問がある人はダウンロードしてみてください。そんでは今年も一年、ご愛読ありがとうございました。皆さん、よいお年を。
                                (2007_12_21)

    ◇編集部から◇
    今回のサンプルプログラムはMOSAのwebサイトからダウンロード可能です。
    http://www.mosa.gr.jp/?p=1475

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

    プログラマのためのオブジェクト指向再入門(35)
    〜XcodeによるPowerPlant X入門(18)〜

     こんにちは、高橋真人です。
     まずは訂正です。前回の説明で一カ所指示が抜けていました。
    PPx::BaseViewをMyViewというサブクラスに変えた段階で、Viewの生成コードも差し替えなければならなかったのですが、その指摘を忘れていました。
     MyApplication.cpのDoSpecificCommand()の中で、前回追加した部分の最後、

    PPx::BaseView *view = PPx::CreateView(contentView, frame,true, true);
    


    MyView *view = PPx::CreateView(contentView, frame,true, true);
    


    と変更する必要があります。あと、ソース冒頭に加えた

    #include 


    #include "MyView.h"

    と変更してください。まあ、このくらいの変更は言われなくても分かった方は大勢いらしたかもかしれませんが。戸惑われた方はすみませんでした。

     さて、それではコードの解説をしておきましょう。
     今回のプログラムは真っ黒な四角が1つ表れるだけの余り面白みのないものです。ですが、ただの黒い四角に見えてもこれはれっきとしたHIViewですから、ここを起点にしていろいろな挙動を加えていくことが可能です。今のうちのシンプルな段階で構造を確実に理解しておくと、あとがラクになると思います。
     では、まずはMyViewです。
     このViewはPPx::BaseViewから継承して作ったサブクラスです。このBaseViewというクラスが、HIViewにおける“Viewのカスタマイズ”にかかわる面倒な部分、特に“Cを使ってオブジェクト指向を実現”したためにいくぶん無理の出ているところをうまく吸収してくれているのです。
     従って、PPxを使う限りにおいてはHIViewの拡張も特に難しいことを考えずに、あたかもHIView自体も最初からC++で作られたフレームワークの一部であるかのような感覚で作業していくことができるようになっています。
     さて、BaseViewは前回の説明でも見ましたように、それ自体だけでは目に見えるようになりません。そのままでもHIViewとしては完全なものであることに疑いの余地はないのですが、ただ単に「そこにあるだけ」では面白くも何ともありませんね。
     そこで、今回作ったMyViewではとにかく表示するようにしました。それには、PPxに用意されている「Viewに振る舞いを加える仕組み」を使っています。
     この表示するための振る舞い以外にも、BaseView(に限らずHIViewを引き継ぐすべてのView)に新たな振る舞いを加えるためのたくさんのクラスがPPxにはあらかじめ用意されています。大掛かりで複雑な仕組みのように見えてしまうかもしれませんが、構造を理解すると、そんなに複雑ではないことがわかるはずです。
     これらのクラスがやっているのは、単にHIView(昔の呼び方ではControl)に関係するCarbonイベントを処理するためのハンドラを付加することだけです。それがCarbonイベントの種類の数だけ用意されていると考えてください。
     その一覧は、PPxViewEvents.hというヘッダファイルの中にあります。もっとも、厳密にはすべてのViewのCarbonイベントをカバーしているわけではなく、実際細かく見てみると足りないものがあることに気付くと思います。ただ、それらは滅多に必要となることのないものですので、既存のものでまず不足することはありません。まあ、それでもどうしても必要になった場合には、自分で簡単に補うことができますので心配はいりません。
     では、動作の仕組みを理解するために、今回のプログラムで使用している
    PPx::ControlDrawDoerを調べてみましょう。
     クラスの定義部分(PPxViewEvents.h:96行目から)を見ていただくと分かるように、このクラスは少し前に解説したコマンドの処理をするクラスと極めて似た形になっています。何よりControlDrawDoerが直接継承しているSpecificEventDoerというクラスは、連載の114回目でCommandProcessDoerが引き継いでいるクラスとして登場したので憶えておいでかもしれませんね。
     実際、ControlDrawDoerの構造を見てみると、CommandProcessDoerと構造が全く同じであることが分かります。HIViewにおいても動作の中心にあるのはCarbonイベントなのでこれは当然のことなのですが、Carbonイベントに慣れていないと少し見通しが悪いかもしれません。ただ、逆に言えば、このPPxでのCarbonイベントの処理パターンが把握できてしまえば、PPxのかなりの部分は理解できたも同然で、あとはその線に沿って必要な形で拡張していくだけで済むのです。

     ここで、少し横道にそれますが、このSpecificEventDoerを継承して作られているこれらのクラスについて、言語の面から見て見ることにします。
     Carbonイベントの処理を行うさまざまなクラスは、すべてが抽象クラスです。抽象クラスについては、連載のかなり前に説明しました(調べてみたら、何と連載の38回目!)が、忘れた方も、読まれていない方もおいででしょうから簡単に解説します。
     抽象クラスというのはそれ自体は実体化(インスタンス化)できないクラスのことです。C++では、純粋仮想関数を備えたクラスを抽象クラスと呼びます。純粋仮想関数というのはクラス宣言の末尾に「= 0」と付いているメンバ関数のことで、この純粋仮想関数を1つでもメンバ関数の持つクラスは抽象クラスとなります。
     最近はオブジェクト指向言語が花盛りで、かつて「実用になる唯一のオブジェクト指向言語」と言われたこともあったC++ですが今や“特殊視”されることも多くなってきたようです。そんな今の時代に書かれたオブジェクト指向の解説を読むと、その多くで“多重継承”を批判的に書かれているのが目立ちます。実際、私も今までいくつものオブジェクト指向言語を使ってきましたが、その中で多重継承を実装しているのはC++だけでした。
     分からない方もおいででしょうから、多重継承についても簡単に解説しておきましょう。
     オブジェクト指向言語において、既存のクラスを元にサブクラスをつくることを“継承”と言いますが、通常は一つのクラスを継承してサブクラスを作るのでこれを“単一継承”と呼びます。
     これに対し既存の複数のクラスを同時に継承することを多重継承と呼びます。
     AとBという二つのクラスがあった場合、この両方のクラスを同時に継承してCというクラスを作ると、新しくできたCというクラスはAのサブクラスでもあり、Bのサブクラスでもあるわけです。両方のクラスを継承していますから、当然両者の性質を共に受け継ぐことになるわけです。
     A、B、それぞれのクラスにDoSomethingというメンバ関数があったとします。単一継承では、AのDoSomethingはBよよってオーバーライドされるので、CのインスタンスがDoSomethingを呼ぶと、呼び出されるのはBのDoSomethingです。(あえてオーバーライドしないことも可能ですが、今はそれは考えません)
     しかし、多重継承の場合、AとBのDoSomethingはオーバーライドの関係にはありませんから、CのインスタンスでDoSomethingを呼び出した時にどちらのDoSomethingが呼び出されるかが特定できません。
     さらに、AとBには実は共通のXというクラスがあって、XでもDoSomethingが定義してあったら? さらに、BにはDoSomethingがなかった場合に、呼び出されるのはどれ?
     このように、最終的にどれが呼び出されるのかが曖昧なのを解決する手段はきちんとC++に用意されてはいるのですが、それでもコードが複雑化することはさけられません。
     そんなこんなの事情があって、多重継承は余り好まれていないのです。詳しく話すともう少しいろいろあるのですが、ここではそんな雰囲気だけを感じてもらえれば充分です。
     もっとも、こうしたやっかいなところを除けば、複数のクラスの機能をミックスして新たなクラスとしてまとめられるのが有意義なわけです。そのためほとんどのオブジェクト指向言語では多重継承を使わずにこれを実現する方法を持っています。Javaではインターフェースというものがそれに当たり、Objective-Cではプロトコルというものがそれに当たります。各言語ごとに呼び方や実現の仕方は異なりますが、この仕組みは一般に“mix-in”と呼ばれます。
     C++においてもmix-inは実現されていて、それには抽象クラスを使うのです。そうすると多重継承にはならず、前述のやっかいさとも無縁でいられるのです。そんなわけで、C++ではほとんど多重継承が使われることはなく、実際、私が今まで経験してきた中でも、一度も多重継承の実例には遭遇していません。
     それでは何でこのようなものがあるのでしょうか?
     そこがC++のC++らしいところです。C++という言語は「書き方の自由度は極力許容するけど、それによって起こるすべても使用者責任で」という考え方の言語なので、言語でそう“書ける”からと言っても、それが“正しい”かどうかはまた別、ということになるわけです。
     まあ、プログラミング言語であれば、多かれ少なかれこの辺は言えるわけで、無秩序に書いてもちゃんと動く言語などあり得ないので、この辺は“程度問題”なのですが、その程度の“折り合いどころ”を議論してもたぶん生産的ではないので、やりません。
     いずれにせよ、先ほども言ったように現代においてC++が“特殊視”されているという状況が世の中のトレンドの一つを示していることは確かなのでしょう。

    開発ツールよもやま話      Xcodeのコード補完    高橋 政明

     レパード(Mac OS X 10.5)で開発環境も大きく変わりました。私自身戸惑うことがありました。時間を取って違いを確認するべきですが常にそうできるとは限りません。まだ翻訳されている資料は少なく、日々の作業に追われている状況ではなおさらです。XcodeUserGuide.pdfは日本語ですが逆に540ページもあり読破するのはタイヘン〔^_^;〕です。

     そこでXocedeを中心としたMac OS X用の開発環境の記事を隔週でお届けしようと思います。なるべく実用的な内容にしたいと思っております。

    ◆Xcodeのコード補完

     初回は先日のMSMの二次会でちょっとだけ話題になったXcodeのコード補完についてです。

     コード補完使っていますか? 私は最近は頻繁に使っています。キーワードのスペルは増々長くなります。正直な所、短くてもそして頻繁に使う語でも正確なスペルを記憶・入力できなくなってきている〔^_^;〕のですが、それはさておきコード補完を利用すると大文字小文字の区別を正確に入力する必要がなくタイピングが楽になるのです。
    設定によりカスタマイズできますがこんな感じです。
    「nsst」までタイプしescを押すと候補がでます。NSStringが選択状態ならリターンを押すだけで入力(確定)されます。

    Xcode2.4では環境設定の「コード入力補助」で設定すると使えます。

    ・環境設定の「コード入力補助」の主な項目(Xcode2.4)索引:すべてのプロジェクトで有効にする
      有効にするとソース内の変数名などローカルなスペルも補完してくれます。
    コードの補完:補完機能を利用できる時に知らせる
      入力中に下線が表示され補完可能なことがわかります。
    ポップアップリストに引数を表示
      引数もあると見分けやすくなりますが横幅も必要です。
    補完用の引数のプレースホルダを挿入
      プレースホルダとは馴染みがない単語ですが、引数に対応する仮の<>で囲まれた語です。
    自動的に候補を表示:しない/メンバーの呼び出し/アクセス時/常に
      三種類から好みで選ぶことができます。候補があればescキーで呼び出せ
      るので私は「しない」を選んでいます。

     候補の一つを選び補完結果を入力すると、引数のある場合最初のプレースフォルダが選択された状態になります。そのまま引数を入力する事ができて便利です。
     次のプレースフォルダへ移るにはcontrolキーを押しながら/(スラッシュ)です。この設定はXcode環境設定のキーバインド/編集/次のプレースホルダを選択で変更できます。『次のプレースフォルダへ移る』のキー設定はMetrowerks互換のデフォルト設定ではcontrol+カンマです。カンマから次の引数を連想できるで私はこちらが気に入っています。

     常にリストがポップアップするのは煩わしいですがXcode3ではコード補完が少し変わりました。候補がポップアップではなく入力行に直接表示されます。この機能をインライ
    ン表示と呼ぶようです。未入力部分は薄く表示されます。リターンで確定、escキーで他の候補がポップアップするのは同じです。

    ・環境設定の「コード入力補助」の主な項目(Xcode3.0)自動的に候補を表示:しない/すぐに/すこし経ってから「しない」以外に設定している場合インライン表示されます。
    そのほかはXcode2.4とほぼ同じです。「補完機能を利用できる時に知らせる」はなくなっています。

    ◆便利なマクロ
     2007年3月にMOSAdeBBの会員談話室にも書きましたがコード補完と同じ操作でマクロを呼び出す事ができます。

    logまでタイプしてescキーを押すと
       

    NSLog(@"<#message#>");


    と展開されます。

    pmだと
       

    #pragma mark <#label#>


    aだと

    [[<#class#> alloc] init]


    aaだと
       

    NSArray * array;


    maだと
       

    NSMutableArray * array;


    nsdだと
       NSDictionary
    nsmdだと
       

    NSMutableDictionary


    とそれぞれ入力されます。

    すべてのリストは
    http://developer.apple.com/documentation/DeveloperTools/Conceptual/XcodeUserGuide/Contents/Resources/ja.lproj/03_03_editing_editor_window/chapter_22_section_7.html
    (日本語XcodeUserGuide.pdfの236ページ「補完プレフィックスのあるテキストマクロ」)に載っています。頻繁に登場するだけにキーのタッチ回数が節約できます。

     私も食わず嫌いであったコード補完機能ですが、今では重宝しています。環境設定で好みに調整できますので試してみてはいかがでしょうか。

    ◆本日のまとめ
    コード補完を上手に使うとタイピングが楽になり生産性が上がります。

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

    2007-12-18

    目次

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

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

      〜Leopard Server Setup編〜

     前回に引き続き標準構成でのセットアップについて解説します。今回は管理者アカウントの登録から解説します。スクリーンショットを用意してありますのでこちらもあわせて参照してください。

    ・セットアップ(標準構成の場合)
    http://www.htabata.com/Site/LeopardServer/Pages/Setup_Standard.html

    ◇管理者アカウント
     「名前」「ユーザ名」「パスワード」を入力するいつもの管理者アカウントの登録です。ただし、Leopard Serverではちょっと注意が必要です。これまでのバージョンではセットアップ中に登録する管理者アカウントはローカルユーザとして登録されていましたが、「標準」構成(ワークグループ構成でも同様)の場合はネットワークユーザとして登録されます。
     「標準」および「ワークグループ」では自動的にOpen Directoryのマスターが構築されます。そしてセットアップ中に登録した管理者アカウントはネットワークユーザとして登録されるのです。この事実をよく覚えておきましょう。あまりないことかもしれませんが、「標準」構成でセットアップしたあとに、Open Directoryの役割を変更してスタンドアロンや複製にしたとします。この場合既存のネットワークユーザは削除され、セットアップ中に登録した管理者アカウントも削除されてしまいます。
     管理者アカウントが削除されてしまうとサーバ管理ができなくなってしまいますが、じつは自動的に「localadmin」というユーザ名のローカルユーザが登録され、このユーザは管理者権限を与えられています。ですのでlocaladminを使ってもサーバ管理ができるということです。localadminのパスワードはセットアップ中に登録した管理者アカウントと同じパスワードが設定されています。
     またrootアカウントにも同じパスワードが設定され、Tiger Serverと同様にLeopard Serverでも最初からrootアカウントが有効になっています。
     「詳細」構成でセットアップした場合のことも解説しておきますと、「詳細」構成では自動的にOpen Directoryのマスターは構築されず、セットアップ中に登録した管理者アカウントはローカルユーザとして登録されます。

    ◇ネットワークアドレス
     デフォルトではDHCPで取得したアドレスを使用しますが、静的なDHCPを使っていなければ固定のIPアドレスを手入力で設定したほうがよいでしょう。サーバですのでアドレスが動的に変わってしまうとサービスに影響が出る可能性があり、あまりよくありません。

    ◇ネットワーク名
     さきほどのネットワークアドレスで設定したDNSサーバ上にあらかじめサーバのレコードが登録されていれば、ネットワーク名は自動的に設定されます。手動で設定する場合、まずプライマリDNS名の設定がありますが、これはDNSで管理される名前を指定します。Tiger ServerではDNSサーバを参照して自動設定されるため、プライマリDNS名をセットアップ中に手動で設定できませんでしたが、Leopard Serverでは手動で設定できるようになりました。
     また、コンピュータ名も設定しますがこちらは「システム環境設定」の「共有」で設定する名前になります。

    ◇時間帯
     時間帯とネットワーク・タイム・サーバを設定します。ネットワーク・タイム・サーバはAppleが提供しているサーバを利用できますが、任意のサーバを指定することもできます。

    ◇サーバのバックアップ作成
     Leopardから導入されたTime Machineを使ってサーバのバックアップを設定します。しかし何をバックアップするのかをあらかじめよく検討しておいてください。たとえばデータベースのデータはロックをかけた状態でバックアップしないとデータの整合性が崩れてしまう可能性があります。
     このような場合にTime Machineを使うには、まずデータベースのバックアップ機能を使って安全な状態でバックアップを作成し、さらにそのバックアップをTime Machineでバックアップするといったやり方が必要になります。さらにリストア方法についても事前に確認しておく必要があります。
     もっともこれはクライアント版のLeopardでも同じことが言えるわけですが、どんなデータをバックアップするのかをよく理解したうえで使用するようにしましょう。

    ◇メールサービス
     セットアップ中にメールサービスの設定をおこなったり、メールサービスを無効にしたりできます。メールサービスの設定はセットアップ後に「サーバ環境設定」を使ってもできますので、ここではまだデフォルトのままでもよいでしょう。ただし、メールサービスを使用しないのであればあらかじめ無効にしておきましょう。必要のないものは動かさなければ、セキュリティを高めることにもなります。

    ◇リモートアクセス
     ここでVPN(L2TP)の設定をおこなうのですが、実際にはセットアップしてもVPNは有効にはなりません。本来VPNの設定をおこなうには共有シークレットやVPNクライアントに割り当てるIPアドレスの範囲を設定する必要がありますが、セットアップ中にこれらを設定することはできません。なぜこのような実装になっているかは不明ですが、VPNを使用する場合にはセットアップ後に「サーバ環境設定」を使って設定しましょう。

    ◇クライアントコンピュータのバックアップ作成
     こちらはTime Machineを使ったクライアント用のバックアップ設定になります。この機能を利用すればクライアントコンピュータのバックアップをネットワーク経由でできるようになります。バックアップの設定をすれば、クライアント上ではサーバをTime Machineのバックアップ先として選択できるようになります。

    ◇ユーザアカウントの追加
     いよいよ最後のセットアップ項目です。セットアップ中にユーザアカウントの登録ができます。アカウントの登録はセットアップ後に「サーバ環境設定」を使ってもできますから、必ずしもセットアップ中に登録する必要はありません。またここでユーザを登録すると、初期パスワードにユーザ名を使うこともできますが、これはセキュリティ上はあまりよくはありませんので、もし初期パスワードをユーザ名にしたのであれば、なるべくはやくユーザにパスワードを変更してもらう必要があります。

    さて、これでセットアップが完了です。セットアップが完了すればこれでいよいよLeopard Serverの運用が可能になります。それでは次回はLeopard Serverで新しく導入されたサービスについて解説する予定です。
                                 次回へつづく

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

    〜 CarbonプロジェクトからInfo.plistを移す 〜

    前回は、プロジェクトの「Japanese.lproj」フォルダに日本語版のMainMenu.nibを追加してみました。今回は、ShinbunShi3プロジェクトのInfo.plistを編集してアイコンを追加してみます。それから、手始めとしてアバウトを表示するようなソースコードを書き始めます。

    前回、「Japanese.lproj」(日本語版nibファイルを含む)を簡単に追加する方法を発見できませんでしたが、フォルダとその中身を作るには、MainMenu.nibを選択し「情報を見る」で表示されるダイアログの「一般」タブの「ローカライゼーションを追加」ボタンを使うことを教えてもらいました(有り難うございました)。しかし、残念ながら、この方法で作成されるnibファイルのメニューも英語表記です(涙)。Interface Builderが日本語ローカライズされたnibファイルを書き出せるわけですから、Xcodeでも指示に従い適切なローカライズnibファイルを出力して欲しいものです。

    ところで、プロジェクトの一覧からMainMenu.nibをダブルクリックすると、必ず英語版のnibファイルがオープンされてしまいます。MainMenu.nibのもうひとつ下の階層に表示される「Japanese」をクリックしないと、日本語版のnibファイルはオープンできません。ならばと言うことで「English」の方を外してみると、今度は何もオープンしません(笑)。Mac OS Xの言語環境が日本語であっても英語版が優先されてしまします。このままだと、知らないうちに間違った言語の方のリソースを編集してしまい、再度アプリを起動して「あれ、何も変化していない?」と悩むことになりそうです。

    アプリケーションがデフォルトリソース(nibファイルやローカライズ文字列)を、どのフォルダから持って来るかについては、 Info.plist「CFBundleDevelopmentRegion」情報で決まります。例えば、ここの設定が「English」で、現在の言語環境が日本語の場合、「Japanese.lproj」が存在すればその中身が使われますが、無い場合には代わりに「English.lproj」の中身が利用されるわけです。そんな訳で、ひょっとしてこの情報を「English」から「Japanese」に変更すれば、ダブルクリックで日本語ローカライズnibファイルの方がオープンされるのかと思ったのですが、結果は駄目でした。

    このままでは日常的な操作環境として少々苦痛なので「Japanese.lproj」はとりあえずプロジェクトから外し、「English.lproj」のリソースを日本語ローカライズして使う事にしました。アプリケーションが完成したら「English.lproj」の中身を「Japanese.lproj」に複製し、英語版ローカライズをやり直すという作戦を取りたいと思います。続いて、「しんぶんし 2.0」で利用していた、Info.plistをそのまま「しんぶんし 3.0」のプロジェクトへコピーして現状ファイルと差替えます。細かな修正は後から行うとして、とりあえずバージョン番号などの記載だけは最新版に変更してみました。

    Info.plistの内容はXMLで記述されていますのでエディタで直接編集してもかまいませんが、プロジェクトのターゲットを選択し「情報を見る」で表示されるダイアログの「プロパティ」タブでも編集できます。CarbonプロジェクトからのInfo.plistには「主要クラス」と「主要Nibファイル」がないので、ここに「NSApplication」と「MainMenu」を入力しておきます。こうしておかないと、Cocoaアプリケーションとして起動できませんので注意してください。Info.plistにはアイコンファイルの名称「ShinbunShi3.icns」も記述されていますので、そのファイルをプロジェクトのResourcesグループに追加すれば、Makeされたアプリケーションにアイコンが表示されます。

    さて、ようやくアプリケーション開発の本作業へ入れる準備が整いましたので、さっそくアバウト表示に挑戦します。Carbonアプリケーションの場合は、Carbon Eventとしてコマンドの’abou’を送信すると、アプリケーションクラスのDefault Handlerがスタンダードアバウトを表示してくれました(Mac OS X10.4から)。この仕組みの実装はCocoaアプリケーションの方が早く、NSApplicationのorderFrontStandardAboutPanel:メソッドを呼び出すことで実現できます。MainMenu.nibでは、MainMenuのアバウト(メニュー項目)はFile’s Owner接続されており、上記メソッドがデフォルトでアサインされています。つまり、このメソッドを独自の物と差し替えれば良いわけです。

    アバウトダイアログ(Cocoaではパネル)を表示する処理自体は大変簡単ですが、初めてCocoaで取り組む場合には考えなくてはいけないポイントがあります。アバウト用パネルオブジェクトはMainMenu.nibの中に作って良いかどうかです。MainMenu.nib内のオブジェクトはアプリケーションが起動された時に、すべて読み込まれてインスタンスが生成されます。NSWindowやNSPanelの場合には、インスペクタの「Visible At Launch」オプションをオフにしておけば、アプリケーション起動時には表示されませんので、後から適切な時点で表示すれば良いことになります。

    そういう訳で小規模なアプリケーションの場合には、すべてのモデル、ビュー、コントローラのオブジェクトをMainMenu.nibに詰め込んでも問題ないですし、その方が管理し易いかもしれません。しかし、大規模なアプリケーションの場合には、関連するモジュールごとにクラスを分けて、必要とされるnibファイルもMainMenu.nibから分離しておくべきでしょう。管理すべきファイルは増えますが、起動時間も短縮でき、開発作業の分担も容易になります。今回は、大規模なアプリケーションではないですが、実験的な意味合いもあるので、アバウトのビューやコントローラは別ファイル(About.nib)として編集してみることにします。

    アバウトメニューの選択で呼ばれるメソッドは、アプリケーション自身のコントローラ(ApplicationController)に用意しておきます。今回は実践練習ですので(笑)アバウトには「OK」ボタンをひとつ用意し、それのクリックでアバウトを閉じるようにしてみましょう。そのためには、NSWindowControllerのサブクラスであるアバウト用のコントローラ(AboutController)も必要です。よって以下のような2つのコントローラ・クラスを準備しました。各クラスのインスタンス変数は、ローカル変数と区別しやすくするためにアンダーバーを含むように表記しています。

    @interface ApplicationConroller : NSObject
    {
       AboutController *about_Controller; // オープンされたアバウトパネル
    }
    - (IBAction)openAboutWindow:(id)sender; // アバウトパネルを開くメソッド
    
    @end
    
    @interface AboutController : NSWindowController
    {
       IBOutlet id ok_Button;         // OKボタンのアウトレット
    }
    - (IBAction)closeAbout:(id)sender; // アバウトパネルを閉じるメソッド
    
    @end
    


    次回は、Interface BuilderでMainMenu.nibとAbout.nibを編集してから、ソースコードを記述し上記の2つのクラスのを実装してみます。Leopardの「XcodeTools」に付属している「Interface Builder 3」は、以前のバージョンから操作体系が大幅に変更されていますので、その辺りを注意深く調べてみたいと思います。
    つづく                                

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

    〜 ドキュメントに使う図のつくりかた その3 〜

     前回は、Graphvizを利用した具体的な作図術を紹介しました。今回は、Pythonをラッパーとして使う「pygraphviz」など、別の角度から見たGraphviz活用術を紹介します。

    ・次のOmniGraffleでGraphvizがサポートされます
     Mac用作図ソフトの定番「OmniGraffle」が、近々バージョン5.0へとアップデートされます。数ある新機能のなかで本連載的に注目なのが、Graphvizのサポート。完全互換というわけではありませんが、シンプルな構成のDOTファイルであれば、そのまま開くことができます。
     第14回以降で紹介したDOTファイルのサンプルを開いてみたところ、第14回のサンプル3点はいずれも開くことができましたが、ノードの形状の書き分けに問題があるようです(「egg」を指定してもOvalのまま)。第15回のサンプルは、リスト2は意図どおり表示されましたが、リスト3の家系図はいくつか線が表示されただけでした。残念ながら、DOT言語完全サポートというわけではないようです。
     なお、OmniGraffle 5.0の動作環境はMac OS X 10.5以降、つまり現時点では
    Leopard専用。Tiger以前のシステムでは起動できないので注意してください。

    OmniGraffle
    http://www.omnigroup.com/applications/omnigraffle/

    ・pygraphvizを使う
     Graphvizには、他のスクリプト言語から利用するための各種ラッパーが存在します。ここに紹介する「pygraphviz」は、名前からもわかるとおり、PythonからGraphvizの機能を利用できるという便利な実装です。
     同じPythonを利用したラッパーとしては「pydot」(http://code.google.com/p/pydot/)もありますが、こちらはすべてPythonで記述さ
    れ、生成したDOTファイルの処理を外部のGraphviz処理系に依存するのに対し、pygraphvizはCで記述され、Graphvizのライブラリを利用して自力でDOTファイルの処理を行います。

    pygraphviz
    https://networkx.lanl.gov/wiki/pygraphviz

     このpygraphvizは、第13回で紹介したCUI版バイナリパッケージ(http://
    www.ryandesign.com/graphviz/)に含まれています。インストールしただけでは利用できないため、ターミナルから以下のとおりコマンドを実行してください。

    - - - - -
    $ export PATH=/usr/local/graphviz-2.14/bin:$PATH
    $ export PYTHONPATH=/usr/local/graphviz-2.14/lib/python2.3/site-packages
    
    ※:インストールしたパッケージにより、「graphviz-2.14」のバージョン名
    部分が異なります。ご自分の環境にあわせ、適宜読み替えてください。
    - - - - -
    


     これでpython対話シェルを起動(ターミナルから「python」を実行)すれば、pythonからGraphvizの機能を利用できるようになります。詳細はチュートリアル(https://networkx.lanl.gov/wiki/pygraphviz/Tutorial)を参照していただくとして、以下の実行例を見れば、どのような処理が可能になるか理解していただけると思います。

    - - - - -
    from pygraphviz import *
    i=AGraph()
    i.add_edge('Namihei','Fune')
    i.layout()
    i.draw("isono.png")
    - - - - -
    


    ・AjaxでGraphvizですか!
     つい最近、面白いサイトを発見しました。T.Ashitani氏の手によるAjaxの機能を利用したGraphvizの実装で、名称もそのまま「Ajax/Graphviz」。WebブラウザのテキストボックスへDOT言語を入力すると、画面へただちに結果が反映されます。いちいちファイルを生成してdotコマンドで処理する手間は不要、インタラクティブに作図できるので、DOT言語の手慣らしに最適です。第15回でサンプルとして紹介した「磯野家家系図」をモディファイしたものを挙げておきますので、コピー&ペーストで試してください。

    Ajax/Graphviz
    http://ashitani.jp/gv/

    - - - - -
    edge [ dir=none];
    node [ fontsize=12,shape=box];
    波平; カツオ;
    node [ fontsize=12,shape=ellipse];
    舟; サザエ; ワカメ;
    node [shape=none,style=filled,height=0,width=0,color=black,label=""];
       "波平_○_舟"; "○_サザエ"; "○_カツオ"; "○_ワカメ";
       { rank=same; 波平; "波平_○_舟"; 舟} 波平 -> "波平_○_舟" -> 舟;
       "○_サザエ" -> サザエ;
       "波平_○_舟" -> "○_カツオ"; "○_カツオ" -> カツオ;
       "○_ワカメ" -> ワカメ;
       { rank=same; "○_サザエ"; "○_カツオ"; "○_ワカメ"} "○_サザエ" -> "○_カツオ" -> "○_ワカメ";
    - - - - -
    
    

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

    2007-12-11

    目次

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

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

    Leopardでは、RubyCocoaで書かれたアプリケーションやスクリプトのサンプルプログラムやプロジェクトが /Developer/Examples/Ruby/RubyCocoa に入っています。中をのぞいて見るとたくさんのフォルダがあります。

    これらの多くはアプリケーションのサンプルです。ターミナルで以下のように入力すると、アプリケーションのサンプルをまとめてビルドすることができます。でき上がったアプリケーションは/Developer/Examples/Ruby/RubyCocoa/apps の中に置かれます。

     $ cd /Developer/Examples/Ruby/RubyCocoa
     $ ruby buildall.rb apps    # ほぼ全てのアプリをビルド
     $ open apps                # Finderでappフォルダを開く
    


    さて、この /Developer/Examples/Ruby/RubyCocoa フォルダの中は、開発初期のサンプルから最近のものまでごちゃ混ぜになっていて、ちょっとわかりにくいかもしれません。ここで主立ったものの概要を上げておきます。

    まずは、この連載でも何回かとりあげている対話型Rubyインタープリタアプリケーションの CocoaRepl.app があります。CocoaReplは、RubyプログラミングやCocoaプログラミングをする上で何かと便利なので、ビルドしたらぜひともアプリケーションフォルダあたりにコピーしておいてください。

    以下は、Cocoa以降に登場したフレームワークを使用しているサンプルアプリ
    ケーションです:

     ・ABPresence          – AddressBook, InstantMessage
     ・CGPDFViewer         – CoreGraphics
     ・CocoaGL             – OpenGL
     ・MiniBrowser         – WebKit
     ・PDFKitViewer        – PDFKit
     ・QTKitSimpleDocument — QTKit
     ・RSSPhotoViewer      – ImageKitを使ったflickrビューア
     ・CITransitionSelectorSample,
       CIBevelSample,
       CIExposureSample,
       CIMicroPaint,       – CoreImage (QuartzCore)

    MailDemoは、3pane構成(メールボックスリスト、メールリスト、メール本文)のアプリケーション(本物のメーラではない)のサンプルを3種類のスタイルで書いたものです。MailDemoActiveRecordBindings は、データベースのバックエンドにRuby on RailsのORマッパである ActiveRecord を使っているところがポイントです。

     ・MailDemoSimple
     ・MailDemoBindings             – CocoaBindingを使用
     ・MailDemoActiveRecordBindings — ActiveRecord/sqlite3

    その他、TypingTutorとRaiseManは、アーロン・ヒレガスの「Mac OS X Cocoaプログラミング」に出てくるアプリケーションをRubyで書いてみたものです。CurrencyConverterは、Key-Valueコーディングの簡単なサンプルをRubyで書いたものです。RoundTransparentWindow と RubyRocks は、RubyCocoaResources
    (http://rubycocoa.com/) のチュートリアルにあるサンプルアプリケーションです。

    ■ 互いに影響しあう動的型付け系言語の世界

    おしまいに余談をひとつ。前述の RubyCocoa Resources の記事を書いたTimBurksさんは、最近、Objective-Cランタイムシステム上で動く、NuというLisp風プログラミング言語を開発しています。

    もともと、CやPascalでプログラミングしていた私が、Rubyにどっぷりはまった結果として、Lispにたいへん心惹かれるようになりました。また、世の中には「なぜRubyは満足できるLispなのか?」(Why Ruby is an acceptable LISP)というタイトルでブログエントリを書いた人もいたりします。

    私は、JavaScriptというプログラミング言語もそこそこ気に入っています。なぜかというと、表面上はCやJavaのような感じですが、その中身がLispくささ濃厚だからのような気がします。prototype.jsというJavaScriptのライブラリをご存知でしょうか? ソースや名前の付け方などを眺めると、どう見てもRubyからの影響を受けまくっているようです。JavaScriptも、Rubyとは違う方向で”acceptable LISP” と言えるかもしれません。

    また、Objectve-C 2.0のproperty構文などは、Rubyの影響なんじゃないかと推測できなくもありません。Objective-Cでは構文として言語仕様を改良して導入するしか手のなかったpropertyのようなものを、目的・問題に応じた疑似構文(DSL Domain Specific Language)としてささっと手軽にプログラミングできるのはRubyの強みです。

    プログラミング言語の世界は、Lispを軸にして、動的型付け系のプログラミング言語が相互に影響しあい中々おもしろい状況になっているようです。

    次回はもっと手を動かす内容にしたいと思います。

    [参考URL]
    RubyCocoa Resources
    http://rubycocoa.com/

    Porgramming Nu
    http://programming.nu/

    Prototype
    http://www.prototypejs.org/

    Why Ruby is an acceptable LISP
    http://www.randomhacks.net/articles/2005/12/03/why-ruby-is-an-acceptable-lisp

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

     
     やれやれあっという間に今年も師走である。年が明けるとサンフランシスコでMacWORLD EXPO。噂の超小型MacBookつうのはホントに出るんですかね。

     ともあれ前回の続き。ツールバーを表示しているウインドウがユーザーによってリサイズされ、その全部を表示できない幅にまで狭められると「>>」みたいな形のアイコンが表示され、それをクリックするとツールバーアイテムがポップアップメニューと、必要ならサブメニューで選択可能になる。が、我々が作成中のツールバーの右端に位置する「Align Text」ではそのサブメニューが出てこない。♪こりゃあどういうわけだ、世の中間違っとるよ(往年のクレージーキャッツの唄です、ご存知ですか?)と思うかも知れないけどこれは世の中が間違ってるんではなく、我々の準備が足りないんである。これが出るようにするには以下のようにする。

     まず、MyApplication.hに以下のアウトレット宣言を追加する。

         IBOutlet NSPopUpButton*  alignPopUpButton;

     これはつまりsampleViewの中にあるあの「Left、Center、Right」のポップアップボタンである。なぜこれが必要かというと、こいつからメニューを引っ張り出して「ウインドウ幅が足りないときに出るメニューのサブメニュー」として使うためですな。もちろんsampleViewのアウトレットが既にあるので、こいつに subViews: を送って返ってきた配列から引っ張り出してもいいんだけど、ここで宣言しておけばその処理にクロックを使わなくて済むからね。
     上の宣言をしたらInterfaceBuilderでMainMenu.nibを開き、このヘッダーをドラッグ&ドロップしてMyApplicationオブジェクトにこのアウトレットを追加。これを「Align Text」のポップアップボタンと連結するわけ。

     済んだらMainMenu.nibをセーブし、MyApplication.m の finishLaunching、
    alignPopというNSToolBarItemを作っている部分に以下のコードを追加する。

     

        NSMenuItem*        alignPopItem = [[[NSMenuItem alloc] init] autorelease];
         [alignPopItem setSubmenu:[alignPopUpButton menu]];
         [alignPopItem setTitle:@"Align Text"];
         [alignPop setMenuFormRepresentation:alignPopItem];
    


     1行目で作っているNSMenuItemは、ツールバーの「>>」をクリックしたときに表示されるメニューに追加するためのものである。こいつにさっき連結したalignPopUpButtonからmenuをひっぱりだしてサブメニューとしてセットするのが2行目。3行目はそのタイトル。そして問題は4行目である。
     setMenuFormRepresentation: というメッセージは読んで字のごとく、このツールバーアイテムの「メニュー形式での表現」を設定するもの。これはmenuFormRepresentation というメッセージで読み出すことができるが、初期値は nil である。で、これを読み出してみて nil の場合、そのアイテムの中身がポップアップボタンだろうがなんだろうが、ツールバーは構わずデフォルトのメニューアイテムを用意する。すなわち名前が見えるだけで右も左も真ん中も選べないあのメニューが表示されるんですな。まぁたとえば「Cat」のように、ただクリックされた(メニューにあっては選ばれた)ことだけわかればいいアイテムはその初期値のままでいいのである。
     ちなみに上のコードを実行するとちゃんとメニューは出るが、もとのポップアップボタンにアイコンがないのでそのアイテムの左にアイコンが表示されない(隣の「Print」は使われているアイコンが小さく表示される)。なんか表示させたいアイコンがある場合には、alignPopItem に対して setImage: でセットすればいい。ただし自動的に小さく表示してくれるわけではないのでサイズは自分で調整すること。
     次回はツールバーの表示モードについて説明して今年の締めくくりとしたい。それでは皆さん風邪などひかぬようご自愛くだされ。
                                (2007_12_08)

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

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

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

     こんにちは、高橋真人です。
     早速、PPx::BaseViewを使ったHIViewの作り方の説明を始めましょう。
     新規にプロジェクトを作成しますが、前回作ったPPxForXcode04は実験用のためのイレギュラーなプログラムでしたので、PPxForXcode03の方を複製して、PPxForXcode05というプロジェクトを作ります。
     各所の03を05に書き換えるための手順は、以前の記事を参考にしてください。

     さて、今回の方針ですが、新規に作成したウインドウの上に動的に(つまり、Nibファイルを使わずに)Viewを作成してみます。
     Viewの作成を行うことのできる個所はいくつかありますが、今回は、アプリケーション側のWindowを生成しているコードのところで一緒に行います。もちろん、このWindowはPPx::Windowをサブクラスした独自のクラスですから、このクラス自体にViewを生成されるようにすることもできるのですが、今回はそのアプローチは取りません。

     それでは、コードに手を入れていきましょう。MyApplication.cpの
    DoSpecificCommand()の中で、

    if (theWindow) {

    という行がありますので、その直後に以下を加えます。(インデントは適宜合わせてください)

    PPx::View *contentView = theWindow->GetContentView();
    HIRect frame = { 40.0, 150.0, 280.0, 130.0 };
    PPx::BaseView *view = PPx::CreateView(contentView, frame, true, true);
    


     とりあえずはこれでOKですが、ソースの冒頭に以下のinclude文を加える必要があります。

    #include 
    #include 
    


     それでは、実行してみましょう。FileメニューからNewを選んでウインドウを作成すると、ウインドウ上にViewが張り付いているのが分かりますね?
     え? 「そんなものは、ない」ですって? いえいえ、決してそんなことはありません。
     実は、ちゃんとViewは存在しているのですが、BaseViewは何も描画を行わないため、目には見えないものになっているのです。
     これでは面白くありませんし、何しろ確認できないので不満が残りますよ
    ね。ですので、次にBaseViewからサブクラスを起こして、ちゃんと目に見えるものにしたいと思います。
     まず、Xcodeで新規のC++クラスをプロジェクトに追加してください。やり方は分かりますね? 分からない方は以前の記事を参考にしてください。あ、クラスの名前はMyViewとしておきましょう。
     以下にコードを掲載します。

    ====================== MyView.h =========================
    
    #include 
    #include 
    
    class MyView : public PPx::BaseView,
                  public PPx::ControlDrawDoer
    {
    public:
       void                Initialize(
                                   PPx::View*      inSuperView,
                                   const HIRect&   inFrame,
                                   bool            inVisible,
                                   bool            inEnabled);
    protected:
       virtual OSStatus    DoControlDraw(
                                   PPx::SysCarbonEvent&    ioEvent,
                                   ControlRef              inControl,
                                   ControlPartCode         inPartCode,
                                   RgnHandle               inClipRgn,
                                   CGContextRef            inContext);
    private:
       virtual void    FinishInit();
    };
    
    
    ====================== MyView.cp =========================
    
    #include "MyView.h"
    
    void
    MyView::Initialize(
       PPx::View*      inSuperView,
       const HIRect&   inFrame,
       bool            inVisible,
       bool            inEnabled)
    {
       BaseView::Initialize(inSuperView, inFrame, inVisible, inEnabled);
    }
    
    void
    MyView::FinishInit()
    {
       EventTargetRef targetRef = GetSysEventTarget();
       PPx::ControlDrawDoer::Install(targetRef);
    }
    
    OSStatus
    MyView::DoControlDraw(
       PPx::SysCarbonEvent&    ioEvent,
       ControlRef              inControl,
       ControlPartCode         inPartCode,
       RgnHandle               inClipRgn,
       CGContextRef            inContext)
    {
    #pragma unused (ioEvent, inControl, inPartCode, inClipRgn)
    
       HIRect frame;
       GetLocalFrame(frame);
    
       ::CGContextFillRect(inContext, frame);
    
       return noErr;
    }
    


     では、早速実行してみましょう。あ、その前にMyApplication.cpの先頭に先ほど加えたinclude文の、
    #include

    #include “MyView.h”と変えておいてくださいね。

     さて、どうでしょう? 今度はちゃんとウインドウ上に黒いViewがあるのがご覧になれたでしょうか?

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

    2007-12-04

    目次

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

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

      〜Leopard Server Setup編〜

     Leopard初のアップデート10.5.1がリリースされました。クライアント版とサーバ版の両方がリリースされています。TigerのころはIntel Macリリース後、クライアント版はPPCとIntel、サーバ版はPPCとUniversalというようにCPUごとにアップデートが分かれていましたが、Leopardではクライアント版もサーバ版もそれぞれ最初からUniversal版として提供されているため、アップデートもUniversal版のみの提供となっています。
     またTigerのアップデート10.4.11もリリースされました。PantherからTigerにアップデートするときは、Tigerのリリース前にPantherの最終OSアップデートがリリースされていましたが、今回はLeopardリリース後のアップデートとなっています。おそらく10.4.11でTigerのOSアップデートは最後かと思いますが、セキュリティアップデートなどは今後もまだリリースされるのではないかと思います。

    ◇標準構成のセットアップ
     さて、それではいよいよセットアップです。前回はLeopard Serverに3つのサーバ構成があることを解説しましたが、「標準」構成でのセットアップについて解説していきます。
     標準では各種サービスが最初から自動設定されるため、将来「詳細」構成に移行する場合でも参考になります。ただし、「標準」と「ワークグループ」は新規インストールの場合しか選択できません。セットアップ画面のスクリーンショットも用意しておきましたので、こちらも参考にしていただければと思います。

    ・セットアップ(標準構成の場合)
    http://www.htabata.com/Site/LeopardServer/Pages/Setup_Standard.html

     なお、セットアップ(インストールも)はリモートでも実行可能ですが、今回の解説ではサーバ機を直接操作してセットアップするものとします。

     インストールが完了するとセットアップの開始です。まずは「ようこそ」画面が表示されます。とっとと次の画面に進みセットアップを開始したいところですが、ここで「Command + Q」でシステム終了することができます。なんで
    これからセットアップが始まろうとしているときに、いきなりシステム終了の話をするのだと思いでしょうが、今後検証などの目的でなんどもセットアップを繰り返したい場合は、ここでまずはシステム終了してシステムのイメージを作成しておくと便利です。
     システム終了してインストール後のボリュームをイメージ化しておけば、インストールディスクを使わなくてもいつでもイメージからインストール直後の状態のLeopard Serverをリストアすることができます。イメージの場合、インストールディスクから再インストールするよりもかなり早くリストアが可能ですので、時間の節約になります。
     イメージの作成方法ですが、もう1台Macがある場合にはFireWireケーブルを用意し、ターゲットディスクモードで起動したLeopard Serverを接続して、
    「ディスクユーティリティ」でボリュームをまるごとイメージ化することができます。またパーティションを分けてMacを使用している場合は、別パーティション上のシステムから起動してイメージを作成することもできます。ちなみにプリンタドライバのインストールを省略して、圧縮してイメージを作成したところ約3.53GBになりました。ちょっとした準備をおこなっておくことで、将来の作業を効率化できるというわけです。イメージは必ず作成しなければいけないというわけではありませんので、もちろんそのままセットアップを続けてもかまいません。

    ◇サーバ構成
     「ようこそ」画面の次は「サーバ構成」の選択画面です。ここで3つのサーバ構成から選択しますが、今回は「標準」を選択します。ファイバーチャネルカードを搭載したマシンでセットアップをおこなう場合は、ここでXsan用の構成を選択することもできます。

    ◇キーボード
     日本語環境でセットアップしている場合はデフォルトで「ことえり」が選択されていますので、そのまま次の画面に進めばよいでしょう。キーボード配列を変更したい場合は「すべてを表示」をクリックすれば他の配列を選択することもできます。

    ◇シリアル番号
     クライアント版のMac OS Xにはシリアル番号はありませんが、サーバではソフトウェアのシリアル番号の入力が必要になります。シリアル番号はOSのパッケージのなかに含まれていますので、客先などでセットアップをする場合は忘れないようにしましょう。シリアル番号が分らないとセットアップが進められません。
     サイトライセンスを使用する場合は「登録名」「登録組織名」も入力します。

    ◇ユーザ登録の情報
     企業または個人情報を入力してユーザ登録をします。Tiger Serverのころはセットアップ中にユーザ登録は求められませんでしたが、Leopard Serverではクライアント版と同様にユーザ登録画面(2画面あります)がセットアップ中に表示されるようになりました。「Command + Q」でスキップすることもできますが、なにも入力しなくても「続ける」ボタンをクリックして次の画面に進むことができます。

     まだセットアップの前半部分が終わったところですが、後半部分は次回解説いたします。
                                 次回へつづく

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

    〜 Carbonからの移住を開始する 〜

    今回からは、最新のXcode 3とInterface Builder 3を使い、新規作成したテンプレート(雛形)プロジェクトを拡張していく作業に入ります。CocoaFrameworkを用いて再開発するアプリケーションは、MOSA Exchangeに登録されている「しんぶんし v2.1」と言うCarbonで開発された対称写真作成ユーティリティです。

    さて、ここから「実況中継」となります(笑)。Carbonからの移植過程で発生したどんな小さな問題点もピックアップして提示したいと思います。まず最初にXcodeを起動してファイルメニューの「新規プロジェクト…」から「アシスタント」をオープンし、開発するアプリケーションの雛形プロジェクトの種類を選びます。「しんぶんし」は、新規ドキュメントを複数オープンするタイプのアプリケーションではありませんので、「Cocoa Document-basedApplication」でなく「Cocoa Application」の方を選択します。

    ちなみに、アプリケーションのモデルオブジェクトのデータ管理用として「Core Data」を採用するという手段もありますが、その場合には「Core DataApplication」を選ぶことになります。しかし、「しんぶんし」はそれほど複雑なメインデータ構造を必要としませんので、とりあえずこのアイデアは却下しました。ただし、通常版の開発が一段落したら、モデルオブジェクトの主役をCore Dataベースへ切り替える作業も実践してみたいと考えています。楽しみは後に取っておきましょう(笑)。

    プロジェクト名は「ShinbunShi3」とします。名称に日本語を使っても問題はないとは思いますが、昔からの癖(防衛本能)で英語表記とします。出来上がったプロジェクトフォルダ内には「English.lproj」が作成されています。
    このフォルダには、英語ローカライズされたMainMenu.nibとinfoPlist.stringsが保存されています。これらは完成したアプリケーションパッケージの「Resources」フォルダ内に複製され利用されます。ところで「しんぶんし3」は全リソースを日本語ローカライズするので、「English.lproj」だけでなく「Japanese.lproj」フォルダも必要となります。

    不思議なことに、Mac OS Xの言語環境が日本語でも、またプロジェクト名を日本語に設定しても、強制的に「English.lproj」が作られてしまい、日本語ローカライズされたファイルを含む「Japanese.lproj」を作る方法が見つかりません。Xcodeの環境設定で新規プロジェクトのディフォルト言語を設定できるかどうか探してみましたが、どうもそうした設定は見当たらないようです(どなたか方法をご存知ありませんか?)。英語メニューのタイトルやアイテムを手動で日本語(ガイドラインに準拠させた)に書き換えるのは結構面倒なので困ってしまいました。

    ところが、Interface BuilderのFileメニュー「New…」から「Choose aTemplate」をオープンし、Cocoaタブから「Appleication」を選ぶと、現在のMac OS Xの言語環境にローカライズされたMainMenu.nib(日本語版)が作成できることが分かりました。それを、新しく用意した「Japanese.lproj」フォルダに保存してやれば、日本語ローカライズされたメニューを表示する事が可能です。また、infoPlist.stringsの方は、旧プロジェクトで使用していた英語版と日本語版の内容を若干変更(バージョン番号を3.0.0に)して再利用することにしました。

    この作業での注意点は、日本語化されているMainMenuオブジェクトをカット&ペーストで別のnibファイルへ移さないことです。ペーストするとメニューの各タイトルにアサインされているアクション(終了ではFirst Responderに対するterminate:)がすべてクリアされてしまいます。にしても、InterfaceBuilderでは日本語ローカライズしたnibファイルを出力できるわけですから、Xcodeでも新規プロジェクトの対象となる言語が何なのかぐらい聞いて欲しいてものです(私がやり方を知らないだけならゴメンナサイ)。

    MainMenu.nibのMainMenuオブジェクトを編集して、アプリケーションメニューの「アバウト」や「終了」アイテムの「NewApplication」表示を「しんぶんし3」(英語用はShinbunShi3)に変えます。 アプリケーションメニューのタイトルは、InfoPlist.stringsの「CFBundleName」の内容が反映されますので、こちらも同様に変更します。メインウィンドウのタイトルも、インスペクタから「画像一覧」(英語版はImage List)に変更します。また、インスペクタの「frame name」に何らかの名称を(今回はMain)代入しておくと、そのウィンドウの表示位置は自動で記録され、次の起動時に前回と同じ位置にオープンされるようになります。

    開発の過程で関連リソースファイル(アイコンや画像)はどんどん増えていきます。そこで、プロジェクトフォルダ内にも「Resources」フォルダを作成して、その中にリソース関連ファイルをまとめておくことにします(整理整頓)。まずそこに「English.lproj」と「Japanese.lproj」を入れ直します。そして、XcodeのプロジェクトウィンドウのResourcesグループに登録されているInfoPlist.stringsとMainMenu.nibの2つを一度外し、新しい保存場所から再登録してやります(リンクの再指定)。

    この時の再登録方法はかなりイレギュラルですので注意してください。「English.lproj」や「Japanese.lproj」フォルダを一覧にドラッグ&ドロップしてもだめです。英語用と日本語用のInfoPlist.stringsとMainMenu.nibを、それぞれ個別にドロップします。登録後に、InfoPlist.stringsとMainMenu.nibの左側の三角をクリックして開くとEnglishとJapaneseという2種類の項目が表示されていればOKです。これにより、プロジェクトは2カ国語
    ローカライズ用リソースを管理可能となったわけです。

    とりあえず今回はここまでとして、プロジェクトをXcodeでMakeして起動させてみます。システム環境設定「言語環境」の言語タブで「日本語」と「English」の優勢順位を切り替えアプリケーションを起動し、それぞれの言語でメニューが表示されるかどうか確認してください。これがうまくいけばローカライズの仕組みは正常に働いています。また、Finderから完成したアプリケーションの情報を表示してバージョンを確認してみてください。そこに
    InfoPlist.stringsに記載した内容が表示されていれば、こちらもOKです。

    次回は、ShinbunShi3プロジェクトのInfo.plistを編集してアイコンを追加してみます。それから、手始めとしてアバウトを表示するようなソースコードを追加してみましょう。 この連載で作成したプロジェクトファイルは、MOSAExchangeに順次アップロードしていく予定です。今回分の名称は「ShinbunShi3_07_11_30.zip」です。
    つづく                               

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

    〜 ドキュメントに使う図のつくりかた その2 〜

     前回に続き、今回も作図ツール「Graphviz」で使うDOT言語の基本的な使い方を紹介します。今回は少々脱線気味ではありますが、Graphvizを知っていただくいい機会になるのでは、と考えています。

    ・磯野家が例題です
     Graphviz / DOT言語の利点は、論理的にグラフ構造を描けることにあります。フローチャートもその一例ですが、ドラマに登場する人物の相関関係のように入り組んだ事柄を、頭で整理しながら図形化できる点が最大のメリットといえるでしょう。
     なにかいい例題は……と考えを巡らしたところ、ありました。日本人なら誰でも知るであろう華麗なる一族、磯野家。これにしましょう。磯野家の家系図であれば、図を使えないメールマガジンであっても、読者の脳裏にダイアグラムを思い浮かばせることができますから。charAやcharBでは、色気もなにもあったもんじゃありませんしね(磯野家にもありませんが)。
     なお、磯野藻屑まで遡ると話がややこしくなるので、波平と舟、カツオとワカメ、そしてサザエ(今回はやむなくマスオとタラオは除外)の計5名を対象にします。家系図の出来上がりには、漢字の「両」のような阪神タイガースのロゴをイメージしてください。

    ・まずは下準備
     家系図を描くとき最低限守らなければならないルールは、男女を描き分けること、世代の違いがわかるよう親子の間に階層を設けることの2つです。前者は男を長方形(box)、女を楕円(ellipse)に書き分けることで対処できそうです。以上を踏まえて作成したDOTファイルが、次のリスト1です。
     node [〜]の使い方は前回も紹介しましたが、以降登場するノードすべてに適用する書式を記述します。「shape=××」としてノードの形状を描きわけている点に注目してください。また、家系図に矢印は使わないため、先頭近くに「edge [ dir=none]」と記述し、矢印なしの線のみとしています。
     

    - - - - -
    リスト1:
    
    digraph {
       edge [ dir=none]
       node [ fontname="Osaka",fontsize=12,shape=box];
       (ここに男性のノードを列挙)
       node [ fontname="Osaka",fontsize=12,shape=ellipse];
       (ここに女性のノードを列挙)
    }
    - - - - -
    


    ・波平と舟の夫婦関係を証明する
     リスト1はまったく不完全な代物で、誰と誰が夫婦か、誰が誰の子なのかがまったくわからない、無階層状態です。まずは、波平と舟が夫婦であるとわかるようにしてみましょう。
     最初に考えつくのは、前回紹介した「A -> B」という記述スタイルだと思いますが、それだけでは不十分です。なぜなら、有向グラフのデフォルトでは上から下に向かってノードが描かれるため、「波平 -> 舟」では親子関係のようになってしまいます。
     そこで利用するのが、「ランク」という概念です。波平と舟のランクが同一になるよう「rank=same」の後に記述しておくことで、横に並べることが可能になります。

    - - - - -
    リスト2
    
    digraph {
       edge [ dir=none]
       node [ fontname="Osaka",fontsize=12,shape=box];
       波平;
       node [ fontname="Osaka",fontsize=12,shape=ellipse];
       舟;
       { rank=same; 波平; 舟} 波平 -> 舟;
    }
    - - - - -
    


    ・いよいよ家系図が完成
     リスト2では、波平と舟が横一列に表示されるようになりましたが、まだまだ不十分です。3人の子供が2人の間から誕生したことがわかるよう、線を子に向けて(1段下のランクへ向けて)引けるようにしなければなりません。しかし、Graphvizでは、線は必ずノードからノードへと引かれるため、波平と舟の中間から線をおろすことができません。
     そこで利用するのが、ダミーのノードを作成する方法です。波平と舟の間に表示されないノード(適当な名前で構いません)を作成し、サザエらの子供たちにつなげます。子供たちにつなげる場合も、直接つなげるとさくらんぼの房のような形に枝分かれしてしまうので、サザエとカツオ、ワカメ用のダミーも作成します(リスト3の8行目)。子供たちのダミーを子供たちの実体のノードと接続すれば、まっすぐ下に向けて線を引けます。
     注意したいのは、波平・舟とすべての子供を「->」でつなぐ必要がないことです。3人の子のうち、中央に位置するカツオと波平・舟(どちらもダミーノード)を接続し、13行目の要領で3人のダミーノードを同ランクに設定&接続すれば、家系図の完成です。

    - - - - -
    リスト3
    
    1: digraph {
    2:  edge [ dir=none];
    3:  node [ fontname="Osaka",fontsize=12,shape=box];
    4:  /* 男性 */ 波平; カツオ;
    5:  node [ fontname="Osaka",fontsize=12,shape=ellipse];
    6:  /* 女性 */ 舟; サザエ; ワカメ;
    7:  node [shape=none,style=filled,height=0,width=0,color=black,label=""];
    8:  "波平_○_舟"; "○_サザエ"; "○_カツオ"; "○_ワカメ";
    9:  { rank=same; 波平; "波平_○_舟"; 舟} 波平 -> "波平_○_舟" -> 舟;
    10: "○_サザエ" -> サザエ;
    11: "波平_○_舟" -> "○_カツオ"; "○_カツオ" -> カツオ;
    12: "○_ワカメ" -> ワカメ;
    13: { rank=same; "○_サザエ"; "○_カツオ"; "○_ワカメ"} "○_サザエ" -> "○_カツオ" -> "○_ワカメ";
    14: }
    - - - - -
    


     今回のポイントは、ランクの設定とダミーとするノードの作成です。この2つのテクニックを理解すれば、Graphviz / DOT言語の使い方も変わってくることと思います。

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