MOSA Multi-OS Software Artists

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

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

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

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

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

    2008-09-30

    目次

    • WWDC初参加レポート
    • 「「Wonderful Server Life」    第78回   田畑 英和
    • ターミナルの向こうから      第33回  海上 忍 

    Wonderful Server Life」  第78回  田畑 英和

      〜「サーバ管理」編〜

     Mac OS X Serverのアップデートがリリースされました。また、他にも色々とアップデートがリリースされていますので今回は最近のアップデートについて解説します。

    ◇Mac OS X Server 10.5.5
     まずはOSのアップデートからですが、今回リリースされた10.5.5はいつものように1つ前のバージョン(つまり10.5.4)からアップデート可能なものと、10.5.0以降からアップデート可能なコンボアップデートの2つが同時にリリースされています。

    ・Mac OS X Server 10.5.5
    http://www.apple.com/jp/ftp-info/reference/macosxserver1055.html
    ・Mac OS X Server Combo 10.5.5
    http://www.apple.com/jp/ftp-info/reference/macosxservercombo1055.html

     OSのアップデートはインストール後にシステムの再起動が必要になりますので、アップデートは計画的に行う必要があります。ところでMac OS X Serverのパッケージもしばらく前にアップデートし、現在では10.5.4のバージョンを購入することができます。
     また、10.5.5のアップデートの詳しい内容はこちらのページで解説されています。

    ・Mac OS X Server 10.5.5のアップデート
    http://support.apple.com/kb/HT2406?viewlocale=ja_JP

     ちょうど前回の連載で、共有ポイントのSMBのプロトコルオプションの設定で、Strict Lockingを有効にできないことを紹介しましたが、10.5.5のアップデートではこの問題が解消されました。

    ◇サーバ管理ツール 10.5.5
     サーバ管理ツールのアップデートもリリースされています。サーバ管理ツールの単体でのリリースは、OSの各アップデートごとにはリリースされず、前回の管理ツールの単体リリースは10.5.3のときでした。

    ・Server Admin Tools 10.5.5
    http://www.apple.com/jp/ftp-info/reference/serveradmintools1055.html
    ・Server Admin Tools 10.5.5について
    http://support.apple.com/kb/HT2667?viewlocale=ja_JP

     10.5.5の「サーバ管理」では、公開されていない修正点も含まれています。「サーバ管理」には、共有ポイントの設定画面で「有効なアクセス権インスペクタ」という機能を使って、特定のユーザに対するファイルやフォルダのアクセス権を確認する機能があります。
     このインスペクタですが、以前のバージョンの「サーバ管理」では日本語環境で実行するとアクセス権をさっぱり確認することができませんでした。日本語環境でインスペクタを表示すると表示領域のスペースが十分でなく、重要なデータを表示できないという、多国語化したアプリケーションでは落ち入りやすい問題があったのです。
     こういった問題があったため、これまでは英語環境で起動するといった回避策が必要でしたが、10.5.5の「サーバ管理」ではようやく日本語環境でも正常に画面が表示できるようになりました。

    ・有効なアクセス権インスペクタ(10.5.5)
    http://www.htabata.com/img/MXS105/acl/acl_10.5.5.png
    ・有効なアクセス権インスペクタ(以前のバージョン)
    http://www.htabata.com/img/MXS105/acl/acl_10.5.png

     安定して稼働しているサーバですと、なかなかアップデートをかけるタイミングというのが難しいところですが、リモートでサーバ管理を行っている場合はサーバのアップデートだけではなく管理端末上のサーバ管理ツールのアップデートも忘れないようにしましょう。

    ◇Apple Remote Desktop 3.2.2
     システム管理にとって欠かせないツールの1つでもあるApple Remote Desktopが3.2.2にアップデートしました。管理ツール用のアップデートとクライアント(つまりApple Remote Desktopで管理対象となるコンピュータのこと)用のアップデートの2つがリリースされています。このアップデートではセキュリティに関する修正も行われています。

    ・Apple Remote Desktop 3.2.2 Admin
    http://www.apple.com/jp/ftp-info/reference/appleremotedesktop322admin.html
    ・Apple Remote Desktop 3.2.2 Client
    http://www.apple.com/jp/ftp-info/reference/appleremotedesktop322client.html
    ・Apple Remote Desktop 3.2.2について
    http://support.apple.com/kb/HT2691?viewlocale=ja_JP

    ◇その他のアップデート
     最近リリースされたその他のアップデートとしては、WebObjects 5.4.2やセキュリティアップデート(2000-006)、10.4と10.5向けのJavaのアップデートなどがあります。

     これらのアップデートはInternetに接続できる環境であればソフトウェア・アップデート経由でインストールできますが、最後にコマンドラインからアップデートを実行する方法をご紹介しておきましょう。
     softwareupdateというコマンドがあるのですが、このコマンドはMac OS X ServerとMac OS Xの両方で使用できます。利用可能なアップデートのリストを確認するには次のようにコマンドを実行します。

    $ softwareupdate -l

     リストを確認するだけであれば通常ユーザでも実行可能です。実際にアップデートをインストールする場合はroot権限が必要になりますので、sudoコマンドと組み合わせて、次のようにコマンドを実行することで、利用可能なすべてのアップデートをインストールすることができます。

    $ sudo softwareupdate -l -a
    


     他にもダウンロードだけを行うオプションや、特定のアップデートだけをインストールするオプションなどあります。なにもオプションを指定せずにただsoftwareupdateとだけコマンンドを入力するとコマンドの簡単な使い方が表示されますので参考にしてください。
    次回へつづく                             

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

    〜 PDFを活用する(4)〜

     前回は、Perlモジュール「PDFJ」で文書レイアウトを行うための基本事項を紹介しました。今回は、PDFJの機能を利用してベクター画像を描いてみましょう。

    ・PDFJでベクター画像を描く
     PDFでは、JPEGのようなビットマップ画像を含むこともできますが、いわゆるテキストボックスのようなレイアウトに関わる文書パーツには馴染みません。その点、拡大しても粗くならないベクター画像は、文書パーツや挿絵のような用途に適しています。
     Perlモジュール「PDFJ」では、前回同様、最初に「use PDFJ」としてモジュールをロードすれば機能を利用できます。主要なメソッドの用法を紹介するためのひな形(リスト1)を掲載しますので、以下に紹介するサンプルコードで実際に試してみてください。

    - - - - -
    リスト1:ベクター画像描画テスト用のひな形
    
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    use PDFJ 'SJIS';
    
    my $doc = PDFJ::Doc->new(1.6, 595, 842);
    my $page = $doc->new_page();
    
    (ここにサンプルコードを挿入)
    
    $zukei->show($page, 0, 0);
    $doc->print("drawtest.pdf");
    - - - - -
    


    ・直線を描く
     直線を引くときは、lineメソッドを使用します。引数は「X1、Y1、X2、Y2、スタイル」の形式で、スタイルの部分で線の太さなどを指定します。以下の例では、ページの左下(0,0)から右上(595,842)に向け、2ピクセルの太さの直線を描いています。

    - - - - -
    my $zukei = Shape->line(0, 0, 595, 842, SStyle( linewidth => 2 ) );
    - - - - -


    注:出力結果は linetest.pdf を参照
    http://www.mosa.gr.jp/?p=2174

    ・スタイルを指定する
     上記のlineメソッドでは、「SStyle」サブルーチンを使い線の幅を指定しています。それ以外にも、表2に挙げたパラメータを与えることで、線の色や破線の条件設定、塗りつぶしの色などを指定できます。以下の例では、線の幅が1.5ポイント、間隔が2の破線、線の色が薄いオレンジの直線を描いています。

    - - - - -
    my $zukei = Shape->line(0, 0, 595, 842, SStyle( linewidth => 1.5, linedash => '2,2', strokecolor => '#CC8C32' ) );
    - - - - -


    注:出力結果は上記URLの styletest.pdf を参照

    - - - - -
    表2:主なSStyleパラメータ
    
    fillcolor => 塗り潰しの色(色オブジェクト)
    linewidth => 線の幅(ポイント)
    linedash => 破線と隙間の長さ
    preskip => 前の間隔(ポイント)
    postskip => 後の間隔(ポイント)
    strokecolor => 線の色(色オブジェクト)
    - - - - -
    


    ・円を描く
     circleメソッドを使うと、円を描くことができます。引数は「X、Y、R、形式、円様式、スタイル」の形で与え、形式には塗りつぶし(f)、線(s)、線と塗りつぶし(sf)の3種類を、円様式には四半円の表示位置(1=右上、2=左上、3=左下、4=右下)を指定できます。SStyleパラメータを使用する場合には、円様式に「0」を指定します。以下のサンプルでは、半径150ポイントの円を描き、内側を緑色で塗りつぶしています。

    - - - - -
    my $zukei = Shape->circle(250, 420, 150, 'f', 0, SStyle( fillcolor => '#00FF00' ) );
    - - - - -


    注:出力結果は上記URLの circletest.pdf を参照

    ・一筆書きで星を描く
     polygonメソッドを利用すると、多角形を描くこともできます。使い方はシンプルで、最初の引数に線として結ぶ点の座標を配列([x1, y1, x2, y2 …])として与え、あとは円と同様に形式(f、s、sf)とSStyleパラメータを指定します。以下の例では、金色に塗りつぶした星を描いています。

    - - - - -
    my $zukei = Shape->polygon([250, 320, 191, 501, 345, 389, 155, 389, 309, 501, 250, 320], 'f', SStyle( fillcolor => '#D6B75B' ) );
    - - - - -


    注:出力結果は上記URLの startest.pdf を参照

    ・図形にテキストを重ね書きする
     図形はshowメソッドで描画され、基本的には実行した順に1枚ずつのレイヤーとして、重ねて配置されます(最新のものが手前)。この順序を変更する場合には、ページオブジェクトのlayerメソッドを操作します。
     たとえば、テキストを出力したあとに図形を描くと、重ねて表示されてしまうため、その部分のテキストを読むことができなくなりますが、テキストを出力する直前にレイヤーの値を(もっとも手前に表示されるよう)高く設定し、その後図形を出力する前にレイヤーの値を低く設定し直せば、その後いくつか図形を出力しようとも、テキストが読めなくなることはありません。

    - - - - -
    $page->layer(100);
    $para->show($page, 30, $paperheight - 100);  #テキストの出力
    
    my $zukei = Shape->circle(250, 420, 60, 'f', 0, SStyle( fillcolor => '#10A0A0' ) );
    
    $page->layer(1);
    $zukei->show($page, 0, 0 );  # 図形の出力
    
    - - - - -


    注:出力結果は上記URLの startest.pdf を参照

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

    2008-09-16

    目次

    • りんご味Ruby         第32回  藤本 尚邦
    • 藤本裕之のプログラミング夜話   #145
    • 高橋真人の「プログラミング指南」  第143回
    • 書籍紹介       Cocoa勉強会会誌 Cocoa Life Vol.4

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

    第27,28回でMechanizeというライブラリについてちらっと触れました。Mechanizeは、Webクライアントを操作するユーザの振る舞いをプログラムするためにあるようなライブラリです。YahooHonyakuのようなものを作るのにはまさにうってつけですね。ということで今回は、YahooHonyakuを実装しなおしながら、Mechanizeを紹介することにします。

    ■ Mechanize

    MechanizeはWebサイトとのやりとり(相互作用)を自動化するためのライブラリで、

     ・cookieの自動送受信
     ・リダイレクトの自動追跡
     ・リンクの管理・追跡
     ・フォームの編集・送信
     ・訪問履歴
    


    などの機能を持っています。いわば、Webクライアントを操作するユーザの振る舞いをプログラムするためのライブラリみたいなものです。インストールにはターミナルでrubygemsのgemコマンドを使います。

     $ sudo gem install mechanize

    インストールが終わったら、ドキュメントのGUIDEやEXAMPLESを見ながら、irbコマンドを使って試してみるとよいでしょう。以降、YahooHonyaku でやるべきことを irb で試していくことにします。

     $ irb --simple-prompt
    require 'rubygems'
    require 'mechanize'

    Mechanizeの核はWWW::Mechanizeクラスです。このクラスのインスタンスがWebクライアントとして振る舞うオブジェクトになります。

     agent = WWW::Mechanize.new                # Webクライアントを生成
     agent.user_agent_alias = 'Mac Safari'     # Safariとして振る舞う
     agent.get("http://honyaku.yahoo.co.jp/")  # HTTP GET
     agent.page                                # サーバが返したページ
    
    WWW::Mechanize#user_agent_alias= メソッドでは、HTTPリクエスト時のヘッダ
    のUser-Agentの値を変更することができます。あらかじめ有名どころのブラウ
    ザの値が準備されていて、'Mac Safari'と指定すると、User-Agentの値が
    Safari と同じものになります。
    
    (補足 agent.user_agent_alias = 'Mac Safari' の `=' は代入構文ではなく、
    インスタンスメソッド WWW::Mechanize#user_agent_alias= の呼出です)
    


    リンクやフォームには以下のようにアクセスします:

     page = agent.page
     page.links                             # 全てのリンク
     page.links.with.text("使い方")         # 「使い方」へのリンク全て
    
     page.forms                             # 全てのフォーム
     page.forms.with.name('textFormEntry')  # textFormEntryフォーム全て
    


    コメントのところにわざわざ「全て」と書いているのは、これらがみなWWW::Mechanize::List というコンテナクラス(Arrayのサブクラス)のインスタンスを返すことを強調するためです。with.name や with.text といったメソッドにより条件で絞り込まれたWWW::Mechanize::List が返されます。

    フォームに関しては、条件にマッチした最初のフォームを返す form_with というメソッドが用意されています:

     form = agent.page.form_with(:name=>'textFormEntry')

    次はフォーム内のフィールドへのアクセス方法です。

     form.fields                           # 全てのフィールド
     form.fields.with.name('text')         # name属性がtextの全フィールド
     form.radiobuttons                     # 全てのラジオボタン
     form.radiobuttons.with.name('eid')    #name属性がeidの全ラジオボタン
    
    フォーム内のフィールド(inputやtextareaなど)の値には、タグのname属性の値
    と同じ名前のメソッドでアクセスすることもできます(name属性の値がRubyのメ
    ソッド名として有効な場合のみ)。
    
     form.text            # "text"フィールドの値
     form.text = "hello"  # "text"フィールドの値を入力
    


    次に、ラジオボタンを操作して翻訳モードを設定しましょう。

     form.radiobuttons.with.name('eid').with.value('CR-EJ')[0].check
    


    with.name と with.value を続けて呼び出すことにより、AND検索のような効果でラジオボタンの絞り込みが出来ます。ここでは、英日モードのボタンを絞り込んでチェックしました。

    以上で、必要な値をフィールドにセットしました。最後に、翻訳を実行して返されたページのフォームから翻訳結果を取り出します。

     form.submit                                   # 翻訳実行
     page = agent.page                             # 返されたページ
     form = page.form_with(:name=>'textFormEntry') # 返されたフォーム
     form.trn_text   # => "こんにちは"               翻訳結果
    


    正しい翻訳結果は得られたでしょうか? ラジオボタンまわりなど、多少フィールドの操作方法に慣れる必要があるかもしれませんが、そこをクリアできれば、とても手軽にWebクライアントの自動化をプログラムすることができそうです。

    ■ [参考] リンク

    Mechanize (リファレンスマニュアル)
    http://mechanize.rubyforge.org/

    GUIDE
    http://mechanize.rubyforge.org/mechanize/files/GUIDE_txt.html

    EXAMPLES
    http://mechanize.rubyforge.org/mechanize/files/EXAMPLES_txt.html

    ■ [参考] Mechanizeで実装した yahoo-honyaku.rb のソース

    class YahooHonyaku
     require 'rubygems'
     require 'mechanize'
    
     def self.translate(mode, text)
       new.translate(mode, text)
     end
    
     def translate(mode, text)
       open_top_page unless top_page_opened?
       html = post_text(mode, text)
       parse_result(html)
     end
    
     private
    
     def open_top_page
       @agent = WWW::Mechanize.new
       @agent.user_agent_alias = 'Mac Safari'
       @agent.get "http://honyaku.yahoo.co.jp/"
     end
    
     def top_page_opened?
       @agent ? true : false
     end
    
     def _eid_(mode)
       mode = mode.to_s.upcase
       case mode
       when "JC" then "CR-JC-CN"
       else           "CR-#{mode}"
       end
     end
    
     def post_text(mode, text)
       eid = _eid_(mode)
       form = @agent.page.form_with(:name=>"textFormEntry")
       form.radiobuttons.name('eid').value(eid)[0].check
       form.text = text
       form.submit
     end
    
     def parse_result(page)
       page.form_with(:name=>"textFormEntry").trn_text
     end
    end
    

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

     さて前回までながながゆるゆると半ば意図的に結論を先送りにしているような調子で「アプリケーションプログラマに未来はあるか」(あれ? 「アプリケーションプログラマは絶滅危惧種か」だったっけ?)というテーマに沿ってそれを考える上で参考になるであろう背景めいたものについて書いてきたわけだが、そろそろ皆さんもお気付きのようにワタシの結論は大変悲観的なものである。

     ひとことで言ってしまえばですね、「パーソナルコンピュータにおけるアプリケーションプログラムの市場というものは大方のヒトが持っているイメージより小さく、コンピュータ・プログラマがアプリケーション・ソフトを開発して継続的に口に糊して行くというのはかなり困難なことである。しかもこの情勢は、パーソナルコンピュータの普及、出荷台数の増加などによって好転する
    ことは期待できない」ってことである。

     いやオレとて書いててツラい。実を言えばここで「ワタシは自分を客観的に見ることが出来るんです、皆さんとは違うんです」とギャグを飛ばそうかと思ったが、フクダは首相を辞めても国会議員だし国会議員辞めても食うに困るこたぁないだろうが、オレの場合この分析が正しいってことはつまり早晩食い詰めるということであり、おマンマの食い上げになったら自分を客観的に見る
    ことが出来てもなんの足しにもならないのである。ホンマ、笑い事ぢゃないっすよ。

     でも、まぁどうもそういう結論であります。さてどうしましょうか。

     政治の話題が出たのでマクラをそっちに放り投げるが、ここ数日自民党の総裁選だってんで、アソウ、イシハラ、イシバ、コイケ、ヨサノ(あいうえお順です、為念)、5人の候補者が雁首並べてピーチクパーチク自らの抱負というか政見というかワタシが総裁に当選したあかつきにはあーしてこーしてめでたしめでたしですみたいなことを喋っているではないか。おれ思うんだがあのヒト達って「具体的」って言葉の意味が全然具体的に解ってないのね。

     イワク「今後数年で年金問題も解決し、国民生活のさまざまな不安を払拭していい国(美しい国ぢゃなくて)を作る」ちうのはわかったが、どうやってそれをするのかって話になるとどいつもコイツも「きちんと」とか「ちゃんと」とか「しっかり」とか「もっこり」とか(最後のはウソです)、そういう「副詞」ばっかりなのな。いままでそれを「きちんとちゃんとしっかり」やって来
    なかったから今このテイタラクなんでしょう? ならばまたぞろ「きちんとちゃんとしっかりやる」なんちうのは全然「具体的」とちゃうでしょうが。

     何を言いたいかと言うと、ワタシは上のような連中とは違うんです、悲観的ながらもそっと具体的に「ほんぢゃどうしましょうか」という議論をしますよ、ということである。すなわち絶滅危惧種たるアプリケーションプログラマが今後の生存競争を生き残っていくための処方せんを考えて行きましょう、と。

     まず第一に考えるのは、前述のごとく小さい市場でも脱落して行く他者を尻目に自分だけは生き残る、その小さい市場の中で生存に必要なエネルギーを(だんだん用語が生物学っぽくなってきたな)確保できる個体はいるというコトである。どのようなアプリケーションなら(これは「どのようなアプリケーションプログラマなら」という問題ではない。解りますよね?)そうなれるの
    か、どのようなアプリケーションが今現在そうなっているのか、を次回からちょっと見て行こう。
                           (以下次回 2008_09_12)

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

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

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

     こんにちは、高橋真人です。早速続きに入ります。
     ウインドウ上で特定のViewを検索するためにFindViewByID()という関数を使うということまでお話ししました。
     この、トップビューを得てそれを基に目的のViewを探すというパターンは、HIViewで行うのと同じです。そうではあるのですが、PPxではHIViewのフレームワークが提供しているHIViewFindByID()を使ってはいません。
     その理由としては、PPxでのViewの識別子がHIViewのものと違うからということも挙げられるでしょう。
     HIViewでは、Viewの識別子としてHIViewIDというものを使います。これは実体的には昔からの技術であるControl Managerでコントロールを識別する際に利用するControlIDと同じものです。定義としては、

    struct ControlID {
      OSType signature;
      SInt32 id;
    };
    typedef struct ControlID ControlID;
    typedef ControlID HIViewID;
    


    というような感じになります。OSTypeというのも実体は32bitの整数型ですから、この識別子を使うと理屈的には40億×40億以上という膨大な固有のIDを作れます。
     ただ、HIViewでプログラムを組まれた方であれば恐らく、「Viewの検索がちょっと面倒だ」と思われたことがあるのではないでしょうか。
     というのは、単に1つのViewを見つけるためにも、HIViewID型の変数を用意し、それに然るべき値を設定してからHIViewFindByID()に渡してやる必要があるからです。
     HIViewが、そんな手間をかけてでもあえて識別子にこのような型を使用しているのは、決して膨大な数の識別子が必要だったわけではなく、単にControl Managerとの互換性を取りたかったからなのだと思います。
     ですが、過去のしがらみを引きずらない方針のPPxではその部分は切り捨て、単純に一つの32ビット値のみをViewの識別子とすることにしたのだと思います。そのようにしたことで、今回のプログラムの例のように、直接関数の引数に100など数値を渡すことが可能になっています。
     では、PPxがこのように識別子の“型”を変えたことによって、HIViewとの互換性をどのように取っているのでしょう。互換性とは何のことを言っているのかといいますと、Interface Builderでの設定の話です。
     以前お話ししたことがあったと思いますが、PPxでは当初はInterface Builderを使ったGUIの編集ツールを使うつもりではなかったのです。恐らく、独自のGUI編集ツールの計画はあったのだと思いますが、Mac OS Xの新技術の導入ペースに追随するためには、独自のGUIツールを使うよりも純正のInterface Builderを使った方がいいと判断し、途中で方針を切り替えました。
     Interface Builderでは、CarbonサイドのViewはHIViewの系列となりますから、Interface Builder上で作成したViewのIDはHIViewIDの型となります。
     PPxでは、HIViewIDに指定された値のうち、idの値(上記、構造体の定義を参照)だけを利用するようにし、それをPPx::Viewの識別子としています。signatureの値は無視しますから、PPxのみで使う場合には、ここの値は入れなくても構いません。
     ところで、この識別子ですが、PPx::Viewのクラス定義の中には定義がありません。どこにあるかというと、PPx::Viewが継承している親クラスのうちの一つ、PPx::Identifiableというクラスの中です。ここに、ObjectIDT型としてmObjectIDというプライベートな変数があります。
     このObjectIDTという型がどういう定義なのかを探っていくと、PPxTypes.hというヘッダファイルに以下のような定義があるのが見つかります。

    struct ObjectIDStruct { };
    typedef IntegerType             ObjectIDT;
    


     今までの説明によればObjectIDTは単なる整数値であるはずなのに、何やらそんな単純なものではなさそうだと思われるかもしれません。実は、ここにはC++ならではワザが使われているため、ちょっとした“事情”があるのです。
     上記の引用部分は、PPxTypes.hファイルにおいては付け足しのようなもので、その前の部分にあるIntegerTypeという名のクラス定義が重要になります。ただ、クラス定義を見ただけでは、これが一体何をしようとしているのかは簡単に分からないと思いますので、少し説明します。
     まず、このクラスが何のためにあるのかということですが、それは「新たな整数型を定義できるようにするため」です。
     ヘッダファイルの冒頭のコメント部分に、この仕掛けの解説があります。英語ですがそんなに難しいものでもないと思うので「読んでいただければ、分かります」と言いたいところですが、それではあんまりなので説明します。
     C++にはオーバーロードという仕組みがあります。簡単に言うと、引数の構成が異なれば、同じ名前の関数を複数定義できるということです。(Cではできません)
     例として以下のようなプログラムを作ってみます。(実際に試される場合には、XcodeでCarbonアプリケーションとして作成してください)

    #include 
    
    void Foo(int a);
    void Foo(long a);
    
    int main()
    {
         Foo(100);
    }
    
    void Foo(int a)
    {
         std::cout << "a is int." << std::endl;
    }
    
    void Fool(long a)
    {
         std::cout << "a is long." << std::endl;
    }
    


     警告が出るかもしれませんが、ビルドはできるはずです。走らせてみると、"a is int."と表示されます。ご存知のようにリテラル値の100の型はintですから、intを引数にしたFoo()が呼ばれるわけです。これが関数のオーバーロードです。
     で、次にプログラムをちょっとだけ変更して以下のようにしてみます。

    #include 
    
    void Foo(UInt32 a);
    void Foo(OSType a);
    
    int main()
    {
         Foo('TEXT');
    }
    
    void Foo(UInt32 a)
    {
         std::cout << "a is UInt32." << std::endl;
    }
    
    void Foo(OSType a)
    {
         std::cout << "a is OSType." << std::endl;
    }
    


     こんどはどちらの関数が呼ばれると思いますか?
     ところが、残念なことにこのプログラムはビルドできません。2番目のFoo()のところで「定義が重複している」旨のエラーが出るはずです。
     どういうことかと言いますと、UInt32もOSTypeも、単にtypedefによって別名を与えられたものであり、実体はunsigned longそのものだからです。
     このような問題をどうやって回避するかが、ここで説明する仕掛けです。(次回に続きます)

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

    2008-09-09

    目次

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

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

      〜「サーバ管理」編〜

     これまで「サーバ管理」を使った共有ポイントの作成やAFPサービスの設定方法について解説してきました。Mac OS X Serverでファイルサービスを実現する場合、クライアントがMacのみの場合はAFPサービスを利用するのが最も効果的ですが、Windowsクライアントなども混在している場合には他のサービスも利用する必要があります。
     これはクライアントのOSによってサポートしているファイルサービスのプロトコルが異なるためです。Mac OS X Serverではファイルサービスとして次のようなプロトコルを使用することができます。

     AFP:Mac向け
     SMB:Windows向け
     NFS:Unix向け
     FTP、WebDAV:マルチプラットフォーム向け

     それでは今回は「サーバ管理」を使ったSMBサービスの設定について解説していきましょう。大まかな設定手順はAFPの場合と同様です。まずは共有ポイントを作成し、次にサービスの設定を行います。

    ◇SMB共有ポイントの作成
     共有ポイントの作成はプロトコルには依存しませんので、AFPのときと同様に「サーバ管理」を使って共有ポイントを作成します。ただし、プロトコルオプションはプロトコルごとの設定になります。

     SMBでもAFPと同様に、共有ポイントごとにゲストアクセスを許可したり、カスタム名を設定することができます。またロックの設定としてoplockとstrict lockingの2種類の設定があります。ただしLeopard Serverではstrict lockingを有効にすることができません。
     また、デフォルトのアクセス権の設定があり、上位のアクセス権を継承したり、特定のアクセス権を設定できたりするのですが、Tiger ServerのころはACLのアクセス権を有効にしていた場合、SMBのデフォルトのアクセス権は設定できませんでした。ところがLeopard ServerではデフォルトでACLのアクセス権が有効であるにもかかわらず、SMBのプロトコルオプションではデフォルトのアクセス権が設定できてしまいます。
     ただし、デフォルトで特定のアクセス権を設定するようにしても実際には反映されないようです。どうもLeopard ServerではSMBのプロトコルオプションの設定がいまいち整備されていません。

    ・「プロトコルオプション(SMB)」設定画面
    http://www.htabata.com/img/MXS105/smb/sharing_01.png

    ◇SMBサービスの設定
     SMBサービスの設定項目はTiger Serverと同じですので、Tiger Serverでの管理経験があれば設定は簡単でしょう。ですが、AFPと同様にデフォルトの状態でもサービスを開始すればすぐにSMBのファイルサービスを提供することができます。設定は「一般」「アクセス」「ログ」「詳細」の4画面から構成されています。

    ・「一般」設定画面
    http://www.htabata.com/img/MXS105/smb/smb_admin_01.png

     ここでは「役割」の設定がありますが、たんにファイルサービスとして使用する場合にはデフォルトの「スタントアロンサーバ」のままでかまいません。

    ・「アクセス」設定画面
    http://www.htabata.com/img/MXS105/smb/smb_admin_02.png

     サービスの設定としてゲストアクセスの設定があります。これもAFPと同様に、実際にゲストアクセスを許可するには共有ポイントごとにゲストアクセスが有効になっている必要があります。

    ・「ログ」設定画面
    http://www.htabata.com/img/MXS105/smb/smb_admin_03.png

     出力するログのレベルを低/中/高の3段階で設定できます。ログは「サーバ管理」から参照することができ、保存場所は「/var/log/samba/log.smbd」です。

    ・「詳細」設定画面
    http://www.htabata.com/img/MXS105/smb/smb_admin_04.png

     ブラウズやWINSに関する設定を行います。このあたりの設定を正しく理解するにはWindowsネットワークに関する知識も必要になってきます。またコードページ(エンコーディング)に関する設定もあるのですが、Leopard Serverではいくら設定を変更しても、デフォルトの「ラテンUS」に戻ってしまいます。プロトコルオプションの設定といい、なんだかLeopard ServerのSMBは不可解な部分がみうけられます。
    次回へつづく                           

    小池邦人のCarbon視点でCocoa探求(2008/09/05)

    〜 ディレクトリなのか? 画像ファイルなのか? 〜

    今回は、addImagesThread:のループ内から呼ばれているaddImagesPath:メソッドのソースコードを解説することからImageBrowserへの画像登録処理の話を続けたいと思います。以下が addImagesPath:メソッドです。

    - (void)addImagesPath:(NSString*)path
    {
       NSArray     *content;
       NSInteger   i,ct;
       BOOL        dir;
    
       [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&dir];
       if( dir )  // パス名はディレクトリを指す
       {
           if( [[NSWorkspace sharedWorkspace] 
                                           isFilePackageAtPath:path]==NO )
           {  // パス名がパッケージではない場合はその内容を得る
               content=[[NSFileManager defaultManager] 
                                                   directoryContentsAtPath:path];
               ct=[content count];  // 配列個数を得る
               for( i=0;i
    


    このメソッドの役割は、ユーザがファイル選択ダイアログで選んだパス名(複数選ぶことも可能)が、ディレクトリ(フォルダ)なのか? 単独の画像ファイルなのか? を判断して処理を切り分けることです。CocoaのFundationフレームワークでファイル処理を実行する場合には、NSFileManagerクラスを用います。実際には、NSFileManagerオブジェクトをその都度確保するのではなく、defaultManagerクラスメソッドを呼び出して、その結果得られたオブジェクトに対してファイル処理用のメッセージを送ります。

    先頭のfileExistsAtPath:isDirectory:メソッドにより、渡されたパス名(NSString)がディレクトリを指すのか? 単独ファイルを指すのか? を判断しています。パス名が単独ファイルであれば、処理をそのままaddImageOne:メソッドへ引き継ぎます。そうではなくパス名がディレクトリを指している場合には、isFilePackageAtPath:メソッドにより、そのディレクトリがパッケー
    ジ構造(Mac OS Xのアプリケーションなど)なのかどうかを確認しています。この判断を怠ると、パッケージ内の画像ファイルもすべて抽出して登録してしまうことになりますので注意してください。

    純粋なディレクトリの場合にだけ、directoryContentsAtPath:メソッドを利用して、その内容をNSArray配列に格納します。この時に得られる内容とはディレクトリか単独ファイルのパス名ですので、配列個数分を再びaddImagesPath:メソッドに渡して再帰処理(リカーシブ処理)を行います。これにより、選択されたディレクトリより下の階層に含まれてる画像ファイルがすべてサーチされ、そのままImageBrowserへと登録されることになります。例えばルートディレクトリを選べば、その下階層の全画像ファイルがサーチされることになりますので、登録できる画像数には何らかの制限(最大数)を付けておいた方が良いかもしれません。

    最終的には、すべての単独ファイルのパス名が抽出されて、以下のaddImageOne:メソッドへと処理が渡ります。

    - (BOOL)addImageOne:(NSString*)path
    {
       NSString            *path1,*comf;
       BOOL                ret=NO;
       ImageFile           *imagef; 
       NSMutableArray      *arry;
       NSFileHandle        *fhd;
    
       if( path1=resolveAlias( (CFStringRef)path ) )  // エイリアスファイルかどうか?
           path=[path1 autorelease];               // エイリアスからのパスを再代入
    
       if( comf=[MyDocument isImageFile:path] )   // 画像ファイルかどうか?
       {
           if( imagef=[[ImageFile alloc] init] )  // 画像ファイルの場合ImageFileを作成
           {
               imagef.path=path;            // パス名を登録
               imagef.type=comf;            // ファイル情報を登録
               [temp addObject:imagef];     // ImageFileをtemp配列に追加
               [imagef release];
               ret=YES;
           }
       }
       else  // それ以外のファイルでは「しんぶんし 3」のドキュメントかどうか判断
       {
           if( fhd=[NSFileHandle fileHandleForReadingAtPath:path] ) // そうである!
           {
               if( arry=[NSUnarchiver unarchiveObjectWithData:
                                                         [fhd availableData]] ) 
               {    // ドキュメント読み込む
                   [temp addObjectsFromArray:arry];  // 内容をtemp配列に追加
                   ret=YES;
               }
           }
       }
       return ret;
    }
    


    addImageOne:メソッドが最初に実行することは、resolveAlias()ルーチンで対象がエイリアスファイルかどうかを調べ、もしそうであれば、それを解析してエイリアスが指している真のパス名を得ることです。残念ながら(何故か今でも)エイリアス処理に関してはCocoaのNSFileManagerクラスでは対応できません。エイリアス関連の処理を行う場合には、懐かしのCarbon Alias Managerを利用します(笑)。ちなみに、今回はフォルダのエイリアスについては無視しています(永久ループに陥る可能性があるため)。

    続いて、そのファイルがImageBrowserに登録できる画像ファイルかどうかを判断します。それに用いているのがisImageFile:メソッドです。もし画像ファイルだと判断されれば、本アプリのモデルオブジェクトであるImageFileを作成して、そこにパス名やファイル情報を登録し、一時的にデータを確保しているtemp配列(NSMutableArray)へ追加します。そして最後に、対象画像ファイルではないと判断されたファイルの中から「しんぶんし3」のドキュメントファイルを見つけ出し、そこに登録されている画像ファイル情報(ImageFileオブジェクト)を抽出してすべてをtemp配列へ追加します。

    次回は、エイリアスファイルに関わる処理をするresolveAlias()ルーチンや、パス名で示されたファイルがImageBrowserで扱える画像かどうかを判断しているisImageFile:メソッドを中心に解説したいと思います。それにしてもゴールは遠いですね(笑)
    つづく                                

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

    〜 PDFを活用する(3)〜

     前回は、Perlモジュール「PDFJ」のかんたんな紹介を行いました。今回は、PDFJを利用したPDF文書作成の基本テクニックを解説します。

    ・前回の補足
     PDFJで欧文を含むテキストを扱う場合は、ハイフネーション処理のために「TeX::Hyphen」モジュールが必要となります。また、フォントや画像をPDFに埋め込むとき「Compress::Zlib」モジュールを使用するため、あわせて入手しておくといいでしょう。Terminalから以下のとおりコマンドを実行すれば、ダウンロードとインストールを一括処理できます。

    - - - - -
    $ sudo -H cpan
    cpan> force install TeX::Hyphen
    cpan> force install Compress::Zlib
    - - - - -
    


    ・文書オブジェクトの作成
     PDFJでは、モジュールをロードするとき文書に使用する文字コードを指定します。デフォルトはシフトJIS(SJIS)ですが、日本語EUC(EUC)やUTF-8(UTF8)も利用できます。以降使用する文字列やフォントのエンコーディングは、このとき指定した文字コードに従います。
     次に、「PDFJ::Doc」を利用して文書オブジェクトを作成します。必要な引数はPDFのバージョンと、ページの幅/高さの3つです。幅/高さの単位には、ポイント(1ポイント=1/72インチ)を使用します。このとき、PDFのバージョンにはAcrobat 3相当のv1.2から、Acrobat 7相当のv1.6までを指定できます。OpenTypeフォントを使用する場合は、PDF 1.6以降を指定しなければなりません。

    - - - - -
    #!/usr/bin/perl
    use utf8;
    use strict;
    use PDFJ qw[utf8];
    
    my $pdfversion = 1.6;
    my $paperwidth = 595;
    my $paperheight = 842;
    my $doc = PDFJ::Doc->new($pdfversion, $paperwidth, $paperheight);
    - - - - -
    


    ・フォントの定義
     テキストオブジェクトは、後述するTextサブルーチンで作成しますが、あらかじめTStyleサブルーチンでフォントの定義を行ったほうがすっきりと記述できます。そしてTStyleで必須の要素が、「font」と「fontsize」です。
     使用するフォントは、文書オブジェクトからnew_fontメソッドを使い、フォントオブジェクトとして生成します。使用するフォントとそのエンコーディング形式を1対で指定することが基本形ですが、現在ではかな・漢字とアルファベットが混在した文書が一般的なため、日本語・英語それぞれのベースフォント名とエンコーディングが対になる形で定義します(和文と欧文を組にする場
    合、欧文はエンコーディング形式を省略可)。以下の例では、和文ベースフォントが「Ryumin-Light」でエンコーディングが「UniJIS-UCS2-HW-H」(Unicode横書き)、欧文フォントには「Times-Roman」を使用しています。

    - - - - -
    my $font = $doc->new_font('Ryumin-Light', 'UniJIS-UCS2-HW-H', 'Times-Roman');
    my $fontSize = 12;
    my $textStyle = TStyle(font => $font, fontsize => $fontSize);
    - - - - -
    


    ・ページの作成
     PDFの各ページは、文書オブジェクトからnew_pageメソッドを使い生成されます。引数にページの幅と高さを与えることができますが、省略すると文書オブジェクト作成時の値が適用されるため、通常は省略します。

    - - - - -
    my $page = $doc->new_page();
    - - - - -
    


    ・オブジェクトの配置とテキストの流し込み
     PDFJでは、テキストや段落などのオブジェクトを配置することで文章を構成します。以下の記述例では、Textサブルーチンを使用してテキストオブジェクトを生成し、それをParagraphサブルーチンで段落オブジェクトに入れ、その中でPStyleサブルーチンを使い段落スタイルを決定しています。なお、段落オブジェクトとの"入れ子"にせず、テキストオブジェクトをそのまま描画してしまうと、文字が多い場合ページからはみ出してしまいます。
     以下のPStyleサブルーチンでは、必須とされる「size」と「linefeed」、「align」を定義しています。sizeでは段落の行方向のサイズ、alignでは揃えの方向(ex. b=行頭)、linefeedでは行送りをフォントサイズに対する比率で指定しています。
     仕上げとして、showメソッドを使いページオブジェクトをレイアウトしています。表示位置の座標は、ページの左下隅を原点(0,0)として、x座標、y座標の順に指定します。

    - - - - -
    my $text = Text("色は匂へど 散りぬるを 我が世誰そ 常ならむ 有為の奥山 今日越えて 浅き夢見じ 酔ひもせず irohanihoheto chirinuruwo wakayotareso tsunenaramu uinookuyama kefukoete asakiyumemishi yohimosesunn", $textStyle);
    my $para = Paragraph($text, PStyle(size => 500, align => 'b', linefeed => '120%'));
    $para->show($page, 50, $paperheight - 100);
    - - - - -
    


     次回は、画像など他のオブジェクトの扱い方について紹介する予定です。

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

    2008-09-02

    目次

    • りんご味Ruby         第31回  藤本 尚邦
    • 藤本裕之のプログラミング夜話   #144
    • 高橋真人の「プログラミング指南」  第142回
    • 書籍紹介       Cocoa勉強会会誌 Cocoa Life Vol.4

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

    今回は、前回作成したHTTP POSTのためのリクエストヘッダとボディを使ってpost_textを完成させます。

    ■ post_textの実装 (rest-open-uri)

    Yahoo!翻訳のトップページを取得(open_top_page)するためのHTTP GETには、Ruby 1.8.6に添付されているopen-uriライブラリを使用しました。open-uriはどうやらHTTP GETのみのサポートのようなので、(HTTP GETではなく)HTTPPOSTする必要があるpost_textの実装には使うことができません。

    open-uriよりも低レベルのHTTPプロトコルライブラリであるnet/httpを使って実装しても大した手間ではないのですが、できることならopen-uriのような手軽な使い勝手でHTTP POSTも扱いたいですね。以前、「Restful Webサービス」という本を眺めていたときに、open-uriのインターフェースを拡張してPOSTやその他のHTTPメソッドを扱えるようにしたrest-open-uriというライブラリを見つけたので、それを使って実装することにします。rest-open-uriはgemコマンドを使ってインストールできます:

     $ sudo gem install rest-open-uri

    では、rest-open-uriを使ってpost_textを完成させましょう:

     require 'rubygems'
     require 'rest-open-uri'
     (中略)
     def post_text(mode, text)
       params = {
         :eid  => _eid_(mode),  # 変換モード(_eid_で正規化)
         :text => text,         # 翻訳したいテキスト
         :key  => @key,         # HTTPレスポンスから取得した値
         :time => @time,        # HTTPレスポンスから取得した値
         :both => "TH"          # (謎のパラメータ、おまじない)
       }
       body = params.map{ |key, val|
         "#{key}=#{CGI.escape(val.to_s)}" }.join('&')
       request = HTTP_REQUEST_HEADER.merge(
         "Content-Type" => "application/x-www-form-urlencoded")
    
       request[:method] = :post   # HTTPメソッドをPOSTに指定
       request[:body]   = body    # HTTPリクエストのボディをセット
       open(URL, request) { |io| io.read }
     end
    


    前半のPOST用のデータを作っている部分は前回作成したコードです。open-uriでは、openメソッドの2番目以降の引数として、リクエストヘッダに相当するHashオブジェクトを渡す仕様になっていますが、rest-open-uriは、このHashオブジェクトに、HTTPリクエストのメソッド(GET、POSTなど)やボディなどを追加指定できるように拡張されています。

    さて、ずいぶんと回り道をしましたが、ようやくpost_textが完成しました。テストしてみましょう:

     $ ruby test-yahoo-honyaku.rb
       (中略)
       1) Error:
     test_s_translate(TestYahooHonyaku):
     NotImplementedError: まだ実装してねぇ、誰か書いてくれ!
         ./yahoo-honyaku.rb:73:in `parse_result'
         ./yahoo-honyaku.rb:14:in `translate'
         ./yahoo-honyaku.rb:8:in `translate'
         test-yahoo-honyaku.rb:19:in `test_s_translate'
    


    これでYahooHonyakuをすべて実装したような気になっていましたが、まだparse_result を実装していませんでした。ささっと実装してしまいましょう。

    ■ parse_resultの実装

    parse_resultの役割は、post_textのレスポンスをパースして翻訳されたテキストを取り出して返すことです。これは実際のところ、open_top_pageの実装(第28回)のときに作ったparse_form!でほとんどできあがっています。ということで、共通部分を整理しつつparse_resultを作ります:

     def parse_html!(html)
       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
       # 翻訳されたテキストを返す
       @form.search("textarea[@name=trn_text]").text
     end
     alias parse_result parse_html!
     alias parse_form!  parse_html!
    


    parse_form! の実装の最後の部分に、HTTPレスポンスから翻訳されたテキストの入っているtextareaを取り出してそれを返すコードを追加して、parse_html!というメソッド名に変更しました。このparse_html!メソッドは、そのまま、parse_form!としてもparse_resultとしても使うことができます。

    alias というのは、メソッドに別名をつけるための構文です。上記のコードでは、parse_html!メソッドに、parse_resultという別名とparse_form!別名をつけていることになります。

    (余談) ずっと前(第5回)に、Rubyでの代入構文は「オブジェクトに名前を付ける」というような意味になる、というようなことを書きました。メソッドを定義するための構文defや、メソッドに別名をつけるための構文aliasも「メソッドに名前をつけること」と考えてもいいかもしれません。

    さて、parse_resultができたところでテストしてみましょう:

     $ ruby test-yahoo-honyaku.rb
     (中略)
     2 tests, 4 assertions, 0 failures, 0 errors
    


    なんとテストを通ってしまいました! irbでも試してみましょう。

     $ irb -r yahoo-honyaku --simple-prompt
     >> y = YahooHonyaku.new
     => #
     >> y.translate(:je, "思いがけずテストを通ってしまった")
     => "I have passed a test unexpectedly"
     >> y.translate(:ej, "I have passed a test unexpectedly")
     => "私は、予想外にテストにパスしました"
     >> y.translate(:je, "ネコ空中大回転")
     => "Cat air giant roll"
    


    だいじょうぶそうですね。:jc,:cjで日中・中日、:jk,:kjで日韓・韓日の翻訳も可能です。

    ということで、ようやくですが、YahooHonyakuライブラリとして機能するようになりました。次回からは、これを使ってコマンドやCocoaアプリケーションを作っていく予定です。

    == YahooHonyakuのライブラリとテストプログラムのソース

    以下のURLに、今回完成したYahooHonyakuのライブラリとテストプログラムのソースを置いてありますのでご覧ください。
    http://www.mosa.gr.jp/?p=2096

    このURLからringoajiruby31.zipをダウンロードしてください。解凍するとringoajiruby31フォルダ内に二つのファイルがあります。

    ライブラリ(yahoo-honyaku.rb)
    ringoajiruby31/yahoo-honyaku.rb

    テストプログラム(test-yahoo-honyaku.rb)
    ringoajiruby31/test-yahoo-honyaku.rb

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

     あっと言う間にオリンピックが終わり、前回原稿で振った話が宙に浮いた状態になってしまったが、要は「北京オリンピックを契機にハイビジョンテレビを買うヒト」と「北京オリンピックを契機にダビング10機能のついた録画機器を買うヒト」の比率ってのは有意に違うでしょ、ということである。

     作って売る側は「オリンピックですオリンピック、4年に1回ですよダンナ、北島選手は金メダル確実だし(そうでした)、星野ジャパンだってやるでしょう(やりませんでしたけどね)。その記念すべき瞬間をハイビジョンで残せるんです、しかもダビング10! 今まで1回ムーブできるだけだったのが、9回もコピープラス1回ムーブできるんです!」と言えばみんな飛びつくと思ったの
    か知らんが(だからオリンピックに間に合うように話をつけたんでしょ?)、そもそもそういうニーズ自体そう大きくないんとちゃうの?

     そんで、オレ、パソコンのアプリケーション・ソフトもここ数年(ようやく話がここに戻ってきましたよ)、この「ダビング10機能搭載機器」みたいに、なんつか「作る側が製品に対するニーズを過剰に見積もっている」ようなモノばかりに見えるのである。

     思えば20数年前のパソコン黎明期(異論もあろうが一応1983年からの16ビットマシン出現以降をこう呼ぶ。それ以前は先史時代)。ふとした弾みで(弾みってこたぁないけどね)パソコンを買ったヒトビト、なかでも仕事半分のオレ達と違って完全に趣味でパソコンを買ってしまったヒトビトは、周囲のヒトから発せられる「そんな高いものを買っていったい何の役に立つの?」という
    質問への答えをそれこそ必死に探していたもんである。

     いわく「字が下手だからワープロを使いたい」「データベースで蔵書を整理する」「MIDIを使って音楽をやる」……その他モロモロ、まぁはっきり言ってその答えに相手が納得するなんてシーンは見かけたことがなかった。口先だけであっても「すごいですね」と感心してもらえればいいほうで、たいがいのばあいは「へぇえ」とか間抜けな声と、昨今の言葉で言えば「ビミョー」な視線をあびせられるのがオチだった。

     考えてみればあれ、ヘンな話でね。趣味のために買うゴルフセットや釣り道具、楽器でもファッションでも鉄道模型でも趣味で買ってる以上、「それが何の役に立つ」みたいな話は(たとえばゴルフセットがビジネスにおける接待の役に立ったとしても、だ)下品だからみんなしないのだ。

     なのに趣味でパソコンを買ったヒトだけは、なんか脅迫されてるみたいにそれが「いかに役に立つか」を説明しなければならなかった。場合によってはプロであっても、家にパソコンを買う時にはなにか家族に言い訳をしたりしたかもしれない。思い当たるヒト、いるでしょ?

     で、ダビング10は知らず、パソコンのアプリケーション・ソフトを企画・制作するヒトの、ニーズを過剰に見積もってしまうという傾向(性向?)には、どっかそういう過去も少しは関係しているような気がするのだよね。以下のような思考回路が働くわけ。

    (1)パソコンで☆▲◎をするのは(できないわけぢゃないけど)結構面倒くさい。
    (2)このソフトを使えばその面倒くささを大幅に軽減できる。
    (3)だからこれを売り出せば☆▲◎をするヒトはみんな買うはずだ。

    でもこれ、見方を変えると「パソコンは役に立たなくちゃいけない」と思い込んでるヒトならではの発想とも言えるのだ。

     そもそもそういうヒトだから「パソコンで☆▲◎をしよう」なんて思うんぢゃないか? 普通のヒトは☆▲◎をするのにパソコンを使わないかも。もしかしたら普通のヒトは☆▲◎自体をしないかもしれない。☆▲◎をするヒトはみんな買うかも知れないが(それも怪しいが)、そうだとしても総数がそれほど多くないのでは?

     ウチの電子レンジにはオーブン機能がついている。だからやろうと思えばオーブン料理ができるのだがやったことはない。その理由の一つは誰にも「この電子レンジ、こんなに便利なんだよ。ほらオーブン料理もできるしさ」と説明する必要がないからで、今はパソコンを持ってるヒトもたぶんそうなのだ。プロのオレ達は「パソコンが役に立つ」ことに拘りすぎている……のかも知れない、と。
    (以下次回 2008_08_30)                       

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

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

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

     こんにちは、高橋真人です。
     早速続きに入ります。
     さて、DoWindowDeactivated()というメンバ関数では、Viewを作った時に付け加えてあったアタッチメントを外す処理を行っています。
     最初に対象となるViewを検索します。
     さて、DoWindowDeactivate()には、引数としてウインドウが渡されてきています。ここで渡されているウインドウはOSネイティブのWindowRefであって、PPx::Windowではありません。
     もっとも、この関数はMyWindowクラス(PPx::Windowを継承している)のメンバ関数ですから、あえてWindowRefを引数に加える必要はないのではないかと思わないでもありません。もし、今処理している関数の中でPPx::Windowオ
    ブジェクトが内部に保持しているWindowRefが必要なら、GetSysWindow()という関数ですぐに取り出すことができますので。
     それでもPPxでは、今までずっと説明してきたように、Carbon上で発生する様々なイベントをPPx::EventDoerを継承の大元とする様々なクラスで処理する構成になっているため、これらの処理を同一のパターンで処理するようになっているのです。よって、このメンバ関数では引数になくても何ら困らないWindowRefも、発生したイベントの中に要素として入っているので、一律に取
    り出して列挙しているということなのです。
     ところで、今回のようにPPx::Windowのメンバ関数ではなく、任意の場所においてWindowRefがあったときに、それをPPx::Windowに変換するにはどうしたらよいでしょうか? その場合には、

    // inWindowはWindowRefの変数
    PPx::Window window = PPx::Window::GetWindowObject(inWindow);

    というように行います。過去に連載の113、116回目あたりで触れていますので、参考にしてみてください。
     ちなみに、このようにしてPPx::Windowに変換できるWindowRefは、あらかじめPPxのオブジェクトとして作られたウインドウに属しているものであることが前提です。PPx::Windowによらない、単に自分で::CreateNewWindow()を呼び出して作ったウインドウを変換しようとしても失敗します。

     本題に戻ります。PPx::WindowのGetWindowContentView()という関数により、ウインドウの保持するView群のルートのViewを得ます。これはHIViewで言うところのroot viewに該当します。つまり、::HIViewGetRoot()と同等の処理をしていると考えるのが妥当です。
     ちなみに、オリジナルのPowerPlantでは“ウインドウもビューの一種である”という考え方で、LWindowはLViewのサブクラスになっていました。PPxではそうではありませんから、PPの経験のある方はこの点を頭に置いておきましょう。

     さて、ContentView(トップビュー)を得たら、次にアタッチメントの付加されているViewを探します。そのためには、ContentViewでFindViewByID()という関数を呼びだします。勘違いされるかもしれませんが、ContentViewが特殊なViewなわけではありません。他のViewと同じくPPx::Viewの普通のインスタンスです。ただ、ウインドウ上のView階層を構成するツリー構造のいちばんトップ(根のところ)にいるために、“唯一の、親を持たないView”であるのが特徴と言えば特徴です。
     Viewの検索はトップビューに対してしか行えないわけではありません。どのViewに対してもFindViewByID()は呼び出せますが、検索の対象がそのViewと、そのView以下(子や孫やその先)の階層が検索の対象となる仕組みです。

     ここでちょっと話が外れますが、階層構造について慣れていない方がおいでかもしれませんので少し触れておきます。

     今、親とか子とか、根などという言葉が出てきました。これらはすべてツリー構造、つまり木のように幹から枝が分かれていくというデータ構造の一種を指しています。「木」と言うと、“一般的な木”を思い浮かべる人がほとんどとは思うものの、中にはモミの木(クリスマスツリーに使われるヤツです)などを思い浮かべたりしてかえって混乱する人も出てくるといけないので
    (笑)、家系図のような階層構造と言っておきます。(この方が誤解する人は少ないでしょう)
     いずれにせよ、一つの基から段階的に複数に分かれていくような構造(データの整理の仕方)を“ツリー構造”とプログラミングの世界では呼ぶわけです。もちろんプログラミングに特有の考え方というわけではなく、家系図にも見られるように世間一般で普通に使われる考え方です。
     昔は、ツリー構造と言うと、アルゴリズムのためのデータ構造がまず頭に浮かんだものですが、最近では、XMLとかオブジェクト指向の継承など、ツリー構造で表現されるものはいくらでも見つかります。Macユーザーの皆さんにとっては、ファインダのファイル階層こそがいちばん身近なツリー構造と言えるでしょうか。
     というわけで、PPxにおいても至るところでツリー構造の考え方が出てきます。一口に親とか子とかいっても、真っ先に自分の頭に浮かんだものだと短絡するのではなく、“どの”ツリー構造のことを言っているのかをちょっとだけ意識しておく必要があるかもしれません。
     ところで、ツリー構造と呼ぶことから、当然“木”をイメージして考える人もいるわけですが、幹から枝に進むことを“上る”というのか“下る”というのかが時々議論になります。リアルな木では、幹もしくは根は下側にありますから、枝に進む場合には当然“上る”になるわけです。
     ですが多くの人(と思うのは私がこっちだから?)は、ルート(根)が上で、下に向かって枝分かれていくイメージを持っているため、枝に進むことを“下る”と表現します。
     要は話がきちんと通じればよいだけですが、世の中にはこのような人もいるのだということを知らずに自分の“常識”だけでやり取りをしていると、とんだ誤解を招いてしまう恐れもありますので注意しましょう。

     ちょっと余談が長引きました。続きは次回にお話しします。

    書籍紹介         Cocoa勉強会会誌 Cocoa Life Vol.4

     解説担当:高橋政明

     Cocoa勉強会の会誌Cocoa Life Vol.4が発売されました。墨一色ながら120ページを超えるボリュームです。
     webで様々な開発情報が得られますが、いざ参照しようとするとアクセスできなかったりもしばしばです。その点書籍などで手元に情報を確保することは現在でも重要です(プログラミングテクニックの一つと言えるかも知れません)。変化の激しい技術情報を日本語で読む事ができるのも助かります。

     下記webで目次と各記事の最初のページが載ったPDFファイルをダウンロードする事ができます。八名の共著による多彩な内容です。各記事の内容をざっとご紹介しましょう。

    ◆QuickLookプラグインの作り方
     LeopardのQuickLookに対応するためのプラグインを作るために必要な情報が
     まとめられています。
    ◆Leopard NSMenu差分
     これまでCocoaでは作れなかった種類のメニューを作る方法と、10.4と10.5
     のメニューの違いが詳しくまとめられています。
    ◆PDF Kit入門 – Leopard変更点
     PDF KitのLeopardでの変更点と以前のバージョンで散見された問題が改善さ
     れた部分などがまとめられています。
    ◆インラインの文字入力
     NSTextInputプロトコルの実例が解説されています。
    ◆DiskImageへSLAを追加する
     ディスクイメージファイルをFinderにマウントする前にソフトウェアライセ
     ンス契約を表示する方法(その表示を日本語などにローカライズするやり方
     を含む)が具体的に紹介されています。
    ◆多言語対応のReadMeファイル
     ReadMeファイルを他言語対応とする独自の方法が紹介されています。
    ◆Uncrustifyでコード整形
     Objective-Cに対応したソースコード整形ツールの紹介記事です。
    ◆識別情報の変換
     文字エンコードとデータタイプを識別する識別情報をCocoaで取り扱う方法
     を具体的に紹介しています。
    ◆カスタムシートとModality
     重要なモーダルなインターフェースについて、シートを中心にサンプルプロ
     グラム付きで詳しく解説されています。
    ◆PaSoRi x Mac 応用編
     FeliCa用カードリーダ/ライタをMac OSで無料で使えるPasoriKitについて
     紹介されています。EdyやSuicaデータの情報もあります。
    ◆DTrace:はじめの一歩
     開発ツールのInstrumentsでもつかわれている、DTraceについての紹介記事
     です。
    ◆HID Manager API
     USBのHIDをアプリケーションで直接扱うサンプルプログラムが解説されてい
     ます。
    ◆Quartzでのインデックス画像の取り扱い
     10.4以降でQuickDraw APIを使わずにインデックスカラー画像を編集する方
     法が解説されています。
    ◆アニメーションGIFの作り方
     Mac OS XでGIFアニメーションを作り保存する方法がファイルのデータ構造
     とサンプルプログラムとともに解説されています。
    ◆CGS プライベート関数の利用
     非公開プライベート関数をアプリケーションから利用しFinderなどで使われ
     ているトランジションを利用する方法が紹介されています。

     Cocoa Lifeは下記webページから購入申し込みできます。
    バックナンバーの情報はこちらにあります。
    http://www.cocoa-study.com/book/

    ▼Cocoa勉強会会誌のweb (サンプルページのpdfあり)
    http://www.cocoa-study.com/book/book4.shtml

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