MOSA Multi-OS Software Artists

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

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

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

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

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

    2008-12-24

    目次

    • りんご味Ruby         第38回  藤本 尚邦
    • 藤本裕之のプログラミング夜話   #151
    • 高橋真人の「プログラミング指南」  第149回
    • mosa entranceだより       第3回   大野 亮一郎

    んご味Ruby   第38回  藤本 尚邦

    前回は、オープンクラスによる疑似的な構文糖衣の実装として、Moduleクラスに直接、アクセッサ宣言のための attr_predicate を定義するコードを示しました。

    --------------------------------------- attr_predicate.rb ---
    Module.class_eval do
     def attr_predicate(*names)
       names.each do |name|
         define_method("#{name}?") do
           instance_variable_get("@#{name}") ? true : false
         end
       end
     end
     private :attr_predicate
    end
    ----
    


    この attr_predicate の定義の中身について、これまでほとんど触れていなかったので、ここで、オープンクラスの定義で登場した class_eval も含めて説明をします。

    ■ class_eval (module_eval の別名)

    class_eval は、既存のモジュールやクラス(=Moduleクラスのインスタンスオブジェクト)に対して、新しい定義を追加したり、既存の定義を変更するときに呼び出すための Moduleクラスのインスタンスメソッドです。Rubyのマニュアル流に表現すると Module#class_eval ということになります。

    Moduleクラスには Module#module_eval というメソッドがあって、実のところclass_eval は module_eval の単純な別名として定義されています。おそらく、メソッドを呼び出すとき、レシーバがクラスならば class_eval、レシーバがモジュールならば module_eval、というように使い分けるために別名があるのでしょう。以下、「クラスはモジュールの一種である」ということを前提に話を進めます。

    class_eval (または module_eval)を呼び出すときには、追加・変更したい定義を、ブロック構文:

     レシーバ.class_eval { ... }      
     レシーバ.class_eval do ... end
    


    または文字列:

     レシーバ.class_eval(プログラム文字列)
     レシーバ.class_eval(プログラム文字列, ファイル名)
     レシーバ.class_eval(プログラム文字列, ファイル名, 行番号)
    


    で与えることができます。定義プログラムを文字列で与える場合には、適切なファイル名や行番号を実引数として与えることにより、プログラム文字列のパース・実行でエラーが発生したときに、エラー情報にエラー発生箇所のヒントを含めることができるようになります。

    上の attr_predicate.rb の定義と同じように、定義をブロックで与える場合には、class_eval ではなく、通常のクラス(あるいはモジュール)の定義構文:

    class クラス名
     ...
    end
    


    を使って、追加・変更したい定義を書くこともできます。

    一見、どちらでもあまり違いがないよう気がしますが、実はひとつ大きな違いがあります。前者(class_evalを使う場合)では、もしレシーバが存在しなければエラーが発生します。一方、後者(classまたはmodule定義構文)では、そのクラス(またはモジュール)が存在する場合には定義の追加・変更を意味するし、存在しない場合には新しいクラス(またはモジュール)の生成と定義を意味します。

    今は既存のクラスに定義を追加・変更するのが目的なので、クラスが「既存」でなければエラーが発生する class_eval を使って定義するのが妥当といえるでしょう(余談 — 1年くらい前に指摘されるまで、私自身もこの大きな違いを意識していませんでした。ちゃんと使い分けるべきでしょう)。

    もうひとつの違いとして、class_evalは、構文ではなくメソッド呼出なので、
    メソッド呼出できるところならどこでも、例えばメソッド定義の中でも、使うことができるというものがあります。ここでその詳細に立ち入ることは避けますが、実はこれも重大な違い(環境、変数などのスコープに関して)になることがあります。

    ■ private 宣言

    def構文による attr_predicate の定義の次に:

     

    private :attr_predicate

    という行があります。これは(直前に定義した)attr_predicateメソッドをprivate なメソッドとして設定します。attr_predicate は、クラス定義時に使うための疑似構文にしたいわけですが、private宣言しないままだと、プログラム中のどこか(つまりクラス定義の外でも)以下のように:

     

    TodoItem.attr_predicate :foo, :bar

    使うことができてしまいます。private宣言することにより、attr_predicate宣言をクラス定義でしか記述できないように制限することができます。

    Ruby においてメソッドを private 指定することは、そのメソッドをレシーバを省略した形式でしか呼び出すことができなくする、つまり、プログラム実行(評価)時に、そのときどきのselfに対してしか呼び出すことができなくするということを意味します。プログラム実行時に、クラス自身(Classクラスのインスタンスオブジェクト)が self になるのはクラス定義のときだけなので、
    private宣言することにより、attr_predicate をクラス定義でしか使うことが出来なくなるわけです。

    (注: Ruby の private は、C++ や Java の private とかなり意味が違います。強いて言えば、派生クラスの定義でも使えるという点で、 C++ や Java のprotected にやや近いかもしれません)

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

     今回の話は、もしかしてあなたが現在学生だったり学生でないまでも20代前半とか、オマケして20代後半から、かろうじて「アラウンド・サーティ」だったりする場合、あんまり当てはまらないと思う。最初にそんだけ言い訳させといてください。では……。ところでモサにそんな若いヒト、いるの?

     承前、前回ワレワレ(ちうかオレ一人だが)が検討したところによれば、たった一人で粉骨砕身努力に努力を重ねてコンピュータゲームを作ることは不可能ではない。だが、時代はそうしたものを商品価値のあるゲームと認めていたところからはるかに遠くイスカンダルのあたりまで来てしまっており、それを射程に入れるにはヤマト総員の気持ちが一つになることが必要なのである……ぢゃなかった、制作チームというか団体戦になってしまう。

     で、オレはそれでもいい、コンピュータゲームの制作チームの一員、そこのプログラマとして働いて食って行きたい、とあなたは言うかもしれない。しかしである。実際のところ、オレもそうだがこれを読んでいるアプリケーション・プログラマのあらかたが、おそらくそういうチームに入れては貰えないだろうという現実がある。

     年寄りは受け付けないってこと? それもある。今をさること25年前、オレがこの業界で仕事を始めた頃には「プログラマ30歳定年説」というのがあってね、「コンピュータの進歩はとっても早いから、だいたい30歳くらいで新しい技術についていけなくなる」なんて言われていた。

     で、オレ達の世代はこれが論理的にまったくスジが通らないばかげた説であることを文字通り体(頭か)で証明してきたんだが、いまだに経営側方面の偉いヒトってのは「若い人=頭が柔軟=新しいことをすぐ覚える=だから最新のテクノロジーについていける」なんて馬鹿なことを信じていて、ただ若いというだけのヒトをヤミクモにプログラマにしようとする傾向がある。

     実際には「コンピュータの進歩はとっても早いから、現在最先端のことを理解するための前提となる知識が短い期間で膨大になってしまい、これからコンピュータのエンジニアになるひとがワレワレのようなある程度のオールラウンダーになれる可能性はとても低い」というほうが正解だよね。でも社会的にはそうぢゃない。

     したがって実力的には申し分ないのに、いやはっきり言えばどんぴしゃの適任の場合が多いのに、年齢が行ってるプログラマはゲームのチームに入れてもらえない。まぁゲームの場合、他のスタッフには文科系、あるいは芸術系が多いので感性として若い(年齢的に顧客に近い)ほうが、という考え方もあるし、そうなるとチームの人間は同世代のほうが……と日本のメーカーは考えがちなんだよね。

     そう、年齢が第一の問題。

     第二の問題は……まぁこれも上のことに絡むんだけど、ゲーム・プロダクション全体の中でのプログラマの重要性が相対的に下がった(他の分野も重要だからね)ため、プログラマに割かれる人件費というものが、プログラマ的(というのはつまりオレ達の常識ということです)に「それはねぇだろ」という水準まで下げられているというのがある。

     実際ゲーム・プロダクションで最もお金を取るのは、ゲームのコンセプトや企画をひねくりだす「ゲームデザイナ」とか「クリエータ」のヒトたちで、プログラマは3Dモデラーとかと共になんつか「工員」レベルの扱いのところが多い。ブーメランのように上の話に戻るけど、スキル不足の若い人を雇うのも、仕事の出来栄えが評価できない以上「安く使える」ということがそのまま「価
    値」になるからである。

     ……と、まるでそれがゲーム業界特有のことのように書いてしまったけど、これは多かれ少なかれ日本におけるソフトウエア・エンジニア、プログラマが共通して直面している問題なんだよね。ここで年を改めて、この、プログラマの仕事に対する世間的評価という話を来年は展開して行きたい。みなさんよいお年を、とは言いにくい状況ではあるが、ワタシもがんばるので皆さんもがんばってくだされ。
    (以下次回 2008_12_19)                       

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

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

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

     こんにちは、高橋真人です。
     前々回から、PPxにおけるEventHandlerUPPの作成・保存・破棄をテーマに解説をしていますが、前回の説明ではC++におけるstatic変数の特徴のお話をしました。このことがどのようにUPPの作成・保存・破棄につながっていくのかということですが、そのためにはシングルトンというものに馴染んでいただく必要があります。
     シングルトンというのは、GoF(*1)の「デザインパターン」(*2)にも含まれるポピュラーなパターンのうちの一つで、一言で言えば「一つのクラスからインスタンスが一つしか生成されないように設計する仕組み」です。
     シングルトンが必要になることは、普通のアプリケーションにおいても所々にあります。中でも一般的と思われるものに初期設定があります。アプリケーションの各種設定内容をまとめて管理するクラスを作ったとして、それを利用する度に新規にインスタンスを生成してしまうと、設定内容にダブりが出たり複数のインスタンス間で内容にズレが出てきたりするなどの問題が起こりますので、初期設定のクラスをシングルトンパターンで実装することは一つの解決策です。

     記事末尾に挙げた参考書籍で例示されているシングルトンパターンのC++での実装例は以下のようになります。(書籍の掲載例を説明に合わせて改変)

    class Singleton {
    public:
       static Singleton* Instance() {
           if (_instance == NULL) {
               _instance = new Singleton;
           }
           return _instance;
       }
    protected:
       Singleton();
    private:
       static Singleton    *_instance;
    };
    


     まず、このSingletonクラスのパブリックインターフェースはInstance()です。staticメンバ関数ですから、Singletonクラスのインスタンスが生成されていない状態でも呼び出せます。
     上記コードでは明示していませんが、唯一のメンバ変数である_instanceはプログラムの起動時にNULLに初期化されます。従って、最初にこのメンバ関数が呼び出された時には条件判断が真になり、インスタンスが1つ作られて_instanceに格納されます。
     2回目以降のInstance()の呼び出し時には、既に_instanceに保持されているインスタンスがそのまま返されるだけとなります。
     このクラスはコンストラクタがprotectedに指定されているため、外部からインスタンス生成することができません。privateではなくprotectedなのは、このクラスがサブクラス化して使われることが想定されているからです。

     さて、このGoFのデザインパターンにおけるSingletonの実装には問題点がいくつかあります。それは、一度作成されたSingletonのインスタンスが決して破棄されることがない、ということです(「破棄できない」ではありせん)。
     C++においてはnewしたものはdeleteして終えるのが作法です。その意味でこのクラスのインスタンスも最終的にdeleteされるべきであるのはその通りなのですが、deleteしなかったからと言って、メモリーリークが起きるわけではありません。
     何故なら、元々シングルトンパターンでは、生成されたインスタンスはプログラムが終了するまで存在することを前提にしていますので、プログラムの終了時にはあえてdeleteを呼ばなくても、メモリの後始末はちゃんと行われます。
     しかし、メモリのリークはないとしても、別のリークが起こる場合があるのです。それはリソースリークです。
     C++では、インスタンスが生成される際に、そのインスタンスの居場所となるメモリの確保を行いますが、同時に、そのインスタンスが必要とする資源の準備をいくつかする場合があります。
     簡単な例では、インスタンスの生成時にファイルをオープンし、インスタンスが破棄される時にファイルをクローズするなどというのが挙げられます。先ほど挙げた初期設定のクラスの場合、最初にインスタンスが生成される際に設定内容をシステムから読み込んでおいて、それをずっとメモリ上に保持しておく。プログラムの終了時、つまりインスタンスの破棄時に、もし設定内容に変更が加えられていたらシステム側の設定内容を更新する、などといったやり方が考えられます。
     このような設計にしておいた場合、上記のGoFのシングルトンの実装例では、システム上の設定内容が更新されることが起こらない、ということになってしまうのです。(破棄時の動作はデストラクタに実装されるが、インスタンスが明示的に破棄されないとデストラクタが呼び出されない)
     そこで、PPxでも使用されているstatic変数を利用したシングルトンパターンの実装方法の登場です。次回はそれを解説します。

    【注記】
    *1 GoF ギャング・オブ・フォーの略で、オブジェクト指向界ではErich Gamma、Richard Helm、Ralph Johnson、John Vlissidesの4人を指す。彼らの書籍(下記)により、デザインパターンという用語がソフトウエアの世界で定着した。
    *2 デザインパターン 技術者が新たなソフトウエアの製作に取り組む際に、過去の経験や知識の中から類似のケースを抽象的に応用することがあるが、これを体系的にかつ一定の規則に基づいてまとめたものをパターンカタログと言う。元々は建築の世界で生まれた考え方であるが、これをSmalltalk界隈のソフトウエア技術者が中心になってソフトウエア界に紹介した。デザインパターンはパターンの中でもデザイン、つまり設計にかかわる部分についてのパターンをカタログ化したもので、「GoFのデザインパターン」と呼ばれる下記書籍にまとめられた23のデザインパターンカタログが最も有名。
    参考書籍:オブジェクト指向における再利用のためのデザインパターンソフトバンク刊 1995年

    mosa entranceだより       第3回   大野 亮一郎

    皆様こんにちは。mosa entranceを主催しております大野と申します。今回は年内最後のモサ伝ですので、今年のmosa entranceを振り返ってお伝えさせて戴きます。

    7月に始まったmosa entranceですが、毎回十数人の皆様にご参加戴いています。回を重ねる度に人数が増え、11月には19名を数えるに至りました。ちょうどiPhoneのSDKが出始めた頃で話題が豊富だったこともあり、iPhoneを目的にMOSAに入会してそのままお越し戴いた方も少なくありませんでした。iPhoneの開発経験は少なくても、MacOSや別環境ではご経験を積んでいらっしゃる方も多かったように思います。mosa entranceのモットーは、初心者と悩めるMacプログラマーに愛の手を! 
    なのですが(笑)、実際には私が考えているよりも猛者にお集り戴いている印象です。もちろん私のような初学者の方もいらっしゃいますが、皆様とても控えめで、非常に幅広い初心者の集いとなりました。

    そんなmosa entranceですが、当初は本当に開催できるのか、一人も来なかったら哀しすぎる…等と不安も多かったものの、無事に回を重ね年末を迎えることができたようです。毎回お茶とお菓子を中心に、MacOSの話、iPhoneについて、またWebアプリケーションについてあーでもないこーでもないと、たくさんのお話をすることができました。高度な話題も少なくなかったのですが、これから腕を磨こうと考えている皆様には、他では得られない有意義な時間になったのではないでしょうか。ひとえに参加戴いた皆様、ご参加は難しくとも応援して下さった皆様のお陰です。

    正直なところ、本当に初心者や悩んでいる皆様のお役に立てる「場」になっているのか自信がありません。試行錯誤しながら進めていますので、ご迷惑をおかけしていることも多いと思います。来年はmosa entranceをよりよい場とするために、ご一緒に道筋のない発展を楽しんで行ければと考えております。ご興味をお持ちの方、どうぞほんの少しだけでも清泉女子大学までお越し下さい。お時間の都合がつかなければ夕食だけのご一緒でも構いません。参加しようか迷っている初心者の皆さん! 思い切って一歩を踏み出してみて下さい!きっとmosa entrnaceで何か新しいものに触れることができると思います。

    改めまして、皆様に今後ともmosa entnraceをご活用戴けます様よろしくお願い申し上げます。

    Merry Christmas and a happy new year!
    どうぞ来年も良い年でありますように!

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

    2008-12-16

    目次

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

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

      〜「iCalサーバ」編〜

     さて今回がiCalサービスの解説の最終回になります。今回はイベントに参加者を設定して他のユーザに通知を送る方法について解説します。ローカルカレンダー上に作成したイベントでも参加者を追加すれば、参加者宛に通知のメールを送信することができますが(ただし、事前にアドレスブックにメールアドレスの登録が必要)、カレンダーサーバ上のイベントの場合はiCal上で通知を
    やり取りすることができます。

    ◇参加者の追加
     まず参加者の追加ですが、iCalサーバ上のカレンダーにイベントを追加し、参加者の欄にユーザを追加します。このとき参加者を直接入力することもできますが、「ウインドウ」メニューから「アドレスパネル」を表示しておくと、ドラッグ&ドロップで参加者を登録することができます。ただしこのとき複数のユーザをまとめてドラッグ&ドロップすることはできないので1人ずつユー
    ザを追加する必要があります。このところはちょっと使いづらいので次のバージョンではぜひとも改善してもらいたいところです。

    ・イベントへの参加者の追加
    http://www.htabata.com/img/MXS105/iCal/iCal_attend01.png

     あらかじめ各参加者の予定を確認しておきたいときは、「空いている時間…」をクリックします。するとイベントを設定した日の各参加者の予定が分かります。ここでは具体的な予定の内容までは分かりませんが、とにかく予定が空いているかどうかは確認できます。各ユーザはiCalの環境設定の「アカウント」であらかじめ基本空き時間を設定しておくこともできます。デフォルトは平日8:00〜18:00と設定できるようになっており、カスタマイズすれば曜日ごとに基本空き時間を設定することもできます。
     空き時間は、イベントを選択して「ウインドウ」メニューから「空き時間状況パネル」を選択することでも確認できます。

    ・空き時間状況の確認
    http://www.htabata.com/img/MXS105/iCal/iCal_Availability.png

     空き時間だけではなく他のユーザの具体的なスケジュールを参照したい場合にはあらかじめ相手のユーザから委任の設定をしてもらう必要があります。この方法は前々回に既に解説済みです。委任が許可されたユーザのカレンダーは「ウインドウ」メニューから参照することもできます。また参照可能なカレンダーはユーザのカレンダーだけではなく、前回紹介した「ディレクトリ」で設定した場所やリソースも、委任の設定がされていれば参照することができます。例えばリソースに対して備品の管理者を委任しておけば、管理者は備品の予約状況をカレンダー上で参照することができます。

    ◇通知の送信と確認
     イベントを作成し参加者を追加すれば、あとは「送信」ボタンをクリックすることによりすべての参加者に通知を送信できます。それぞれの参加者はiCal上で通知を受け取ることができます。現バージョンでは通知はプッシュされませんので、最新の通知を確認するには「カレンダー」メニューの「更新」を選択します。またiCal起動時には自動的に通知の確認が行われます。
     通知を受け取った参加者は仮承認/欠席/参加のいずれかから回答を選択することができます。欠席と回答した場合には主催者に通知が送信されますが、参加と回答した場合には通知は送信されません。参加または仮承認と回答した場合には参加者のカレンダーにもイベントが自動登録されます。自分の状況は後から変更することもできます。

    ・通知の確認
    http://www.htabata.com/img/MXS105/iCal/iCal_attend02.png

     主催者は自分のカレンダーイベントを確認することで各参加者の参加状況を確認できます。また、イベントを削除したような場合にはキャンセルの通知が参加者に送信されるようになっています。イベントの日時が変更された場合も参加者に再度通知が送信され、あらためて参加の有無を確認できるようになっています。

    ・参加状況の確認
    http://www.htabata.com/img/MXS105/iCal/iCal_attend03.png

    ◇iCalサーバのデータ
     さて以上がiCalサービスの解説になります。最後にサーバ上でどこにiCalのデータが保存されているかを紹介しておきましょう。データの保存場所は次のパスになります。

    ・iCalデータの保存場所
       「/Library/CalendarServer/Documents」

     このディレクトリはオーナーが「_calendar」となっており、root権限がないと中身を参照することができません。このディレクトリには各ユーザのスケジュール情報が保存されますので取り扱いには注意が必要です。またiCalサービスの設定ファイルですがこちらは次のパスに保存されています。

    ・iCalデータの設定ファイル
       「/etc/caldavd」

     来年リリースが予定されているSnow Leopardですが、これにはiCal Server2が搭載されることになっており、グループカレンダーや通知のプッシュ、非iCalサーバユーザへのメールでの通知、Webブラウザからのカレンダーの参照などが新機能として予定されています。
    次回へつづく                             

    小池邦人のCarbon視点でiPhone探求(2008/12/12)

     〜 テンプレートを選ぶことから 〜

    今回から、XcodeとInterface Builderを利用したiPhoneアプリケーションの開発に取り組んでいきたいと思います。まずは、Xcodeで用意されているiPhoneアプリケーション用のテンプレート(雛形)プロジェクトを調べてみることにします。

    iPhoneアプリケーションでは、ユーザの作業対象(表示の状態など)を変更する場合に、ウィンドウを切り替えるようなことはしません。代わりに「UIViewのみ」(Mac OS XであればNSView)もしくは「UIViewControllerとUIViewのペア」を切り替えて対応することになります。つまり、iPhoneではスクリーン上に表示されているウィンドウは常にひとつだけとなります(複数用意してもかまわないのですが…)。そういう意味では、Mac OS X用アプリケーションと
    は若干様子が異なります。

    このようなiPhone独特の仕組みを念頭に置き、Xcodeが用意しているテンプレートの種類を確認してみます。Xcodeをアプリケーションから起動し、ファイルメニューから「新規プロジェクト…」を選択すると、テンプレートを選択するためのダイアログが表示されます。まず最初に、左側の対象OSとソフト種類から、iPhone OS直下の「Application」を選んでおきます。すると、右側に選択可能なテンプレート用アイコンが並びます(下に表示される説明は残念ながら英文のまま)。若干意味不明のアイコンもありますが(笑)こうしたテンプレートは、目的別に全部で6種類用意されています。

    ・Window-Based Application

    「Window-Based Application」は、nibファイル(MainWindow.xib)に登録されているUIWindow(UIViewのサブクラス)に対して描画を実行するアプリケーションを作成します。UIWindow上にビューやコントロールを配置したり、そこへQuartz 2D APIでダイレクトに2D描画を実行することで、アプリケーション機能を実現します。Mac OS Xで例えると、モニターのスクリーン上に必要なGUIを設置して、すべての処理を完結させてしまうタイプのアプリケーション
    だと考えれば良いでしょう(例えばFront Rowなど)。このテンプレートが提供しているのが、一番簡単なiPhoneアプリケーションの構造です。

    ・OpenGL ES Application

    「OpenGL ES Application」は、UIWindow(UIViewのサブクラス)上にひとつだけUIViewを配置し、それをEAGLViewクラスと定義してから、その内容をソースコードで実装します。そしてUIViewの幾つかのメソッドをオーバライドすることで、EAGLView上にOpenGL APIによる3D描画ができる環境を形成します。Mac OS XのCocoaならば、スクリーンと同サイズのウィンドウをオープンし、その上にNSOpenGLViewを配置した状況だと考えてください。またCarbonであれ
    ば、スクリーン自体をOpenGL描画環境で「キャプチャ」した状態と同じです。これは、一般的な3Dゲームを開発するのに向いているテンプレートです(ところで何故アイコンは碁盤なのでしょうか?)。

    ・View-Based Application

    「View-Based Application」では、 nibファイル(MainWindow.xib)にUIWindowとUIViewControllerが用意されています。そして、このUIViewControllerのサブクラスをソースコードを記述し実装します。また、UIViewControllerで使われるUIViewは別のnibファイルとして保存されており、アプリケーション起動時に、このUIViewがスクリーン全体に表示されます。前のふたつのテンプレートでは、UIWindowは単にUIViewを置く場所でしたが、UIViewControllerの方は、Cocoaのウィンドウと似た機能をアプリケーションに提供します。Mac OS X的に言えば、ダイアログやウィンドウをひとつだけオープンし、それですべての処理を完結させるタイプのアプリケーションを開発する時に使うと考えてください。そういう意味では、このテンプレートは「ViewController-Based Application」と呼んだ方が良いかもしれません。

    ・Utility Application

    「Utility Application」では「View-Based Application」と同じように、nibファイル(MainWindow.xib)にUIWindowとUIViewController(RootViewController)を用意します。しかしView-Based Applicationの時とは異なり、RootViewController経由で操作するのは、MainViewControllerとFlipsideViewControllerの2つのUIViewControllerです。このふたつのクラスはソースコードで実装されます。それぞれのUIViewControllerに配置される
    UIViewの方は、MainView.xibとFlipsideView.xibという二つのnibファイルに保存されています。このテンプレートでは、用意した2つのUIViewControllerをCore Animationの機能を使い切り替えることが可能で、ダッシュボードの「Widget」をiPhone内に実現した感じとなります。 Mac OS X的に言えば、あるウィンドウから別ダイアログを表示して処理を続けるタイプのアプリケーションです。

    ・Navigation-Based Application

    「Navigation-Based Application」は、nibファイル(MainWindow.xib)にUIWindowとUINavigationControllerを用意します。UINavigationControllerはUIViewControllerを継承しており、複数のUIViewControllerを管理し、その表示を切り替える機能を利用できます。ここでは、管理対象としてUIViewController(RootViewController)がひとつだけ用意されていますが、テンプレートを拡張して複数のUIViewControllerを追加することが可能です。ちなみに、RootViewControllerクラス自体はソースコードで実装されています。RootViewControllerで利用されるUIView(UITableView)は、別のnibファイルであるRootViewController.xibに用意されています。Mac OS X的に言えば、目的に応じて階層化された複数のウィンドウを切り替えることで作業を進めるタイプのアプリケーションだと考えれば良いでしょう。

    ・Tab Bar Application

    「Tab BarApplication」では、nibファイル(MainWindow.xib)にUIWindowとUITabBarControllerが用意されています。このUITabBarControllerのタブ数は2に設定されています。ひとつ目のタブをタップして表示される内容は、FirstViewControllerクラスとしてソースコードで実装されていますが、ふたつ目のタブのタップで表示される内容は、nibファイルのSecondView.xibに登録されているUIViewです。ユーザがタップ可能なタブの数を増やせば、さらに多くのUIViewControllerやUINavigationControllerを管理することが可能です。機能的にはウィンドウ上に配置したタブコントロールに似ているのですが、Mac OS X的に言えば、多数のウィンドウを切り替えて作業を行う大規模なアプリケーション向けのテンプレートです。

    上記のアイコンのうちのひとつを選んで下の「選択…」ボタンを押してからプロジェクト名を入力すると、保存先に必要なファイル(Objective-Cソースファイルやnibファイルなど)をすべてまとめたプロジェクト用フォルダが作成されます。この時のプロジェクト名にはなるべく日本語を使わないでください(使おうと思えば使えますが…)。出来る限り開発アプリケーションの「名称」そのものにしておくと、後で煩わしい変更作業が必要なくなります。

    開発の第一歩は、自作アプリケーションの機能や構成に向いたテンプレートを選択することです。よって、Xcodeがどんなテンプレートを「はき出す」のかを熟知していることは大変重要です。例えば「App Store」で販売されているiPhoneアプリケーションが、どのテンプレートから開発されているのかを推測するのも勉強になります。現状では、ゲームやパズルが多いので、ほとんどは
    「Window-Based Application」や「OpenGL ES Application」のような気がしますが(笑)。

    さて、iPhone用の「しんぶんし」の開発には、どのテンプレートを使いましょうか? とりあえず「Navigation-Based Application」が向いているような気もしますが、その結論は宿題として次回まで取っておくことにしましょう。

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

    〜 いま敢えて学ぶTerminalのイロハ(5) 〜

    ・「パス」を理解するための予備知識
     コマンドを入力してENTERキーを押すとコマンドの機能が実行される — 当たり前のように使っている機能ですが、これにはいくつかの約束事があります。
     まず、コマンドを実行するという処理が、シェルによって実現されていることを認識しなければなりません。シェル(初期設定では「bash」)がENTERキーを合図に、現在入力を受け付けている行をコマンドラインとして解析し、コマンドと判断された部分 — 通常は行頭 — を探して実行する、という意味です。
     シェルがコマンドとして認識した文字列は、特定のディレクトリを対象に同名の実行形式ファイルが検索されます。この検索対象のディレクトリは、すなわちコマンドの保存場所であり、Leopardの初期設定では/binと/sbin、/usr/binと/usr/sbin、/usr/local/binと/usr/X11/binが設定されています。言い換えれば、これらのディレクトリに保存されている実行形式ファイルが、シェルがコマンドとして認識しているプログラムです。

    ・「パスが通っている」の意味
     では、他のディレクトリにコマンドは保存できないか? というと、そうではありません。前述したディレクトリは、環境変数「PATH」で定義され、それをシェルが参照しているに過ぎません。PATH環境変数を再定義することにより、シェルが認識可能なディレクトリであればコマンド置き場として利用することが可能です。
     前置きが長くなりましたが、このPATH環境変数こそが「パス」であり、コマンドが保存されたディレクトリがPATH環境変数に登録された状態を「パスが通っている」といいます。「パス」はコマンドサーチパスともいいますが、単に「パス」と呼ぶほうが一般的です。ちなみに、PATH環境変数を定義/再定義してコマンドの保存場所をシェルに知らせる処理は、「パスを通す」といいます。

    ・シェルも工夫しています
     先ほど「コマンドを検索している」と書きましたが、これには少々語弊があります。実際には、シェルはコマンド名と保存場所の対応表(ハッシュテーブル)を作成し、コマンド実行時における処理の高速化を図っています。
     bashには、常にハッシュテーブルを最新の状態に保つ機構が装備されています。PATH環境変数が定義/再定義されたとき、コマンドを追加するなどパスの通ったディレクトリの内容が変更されたときには、ハッシュテーブルも自動的に更新されるため、その存在を意識する必要はありません。
     なお、bash以外のシェルは多少事情が異なります。たとえば、以前Mac OS Xで標準のシェルに採用されていた「tcsh」は、コマンドを追加したあとは内部コマンドの「rehash」を実行し、ハッシュテーブルを明示的に更新する必要があります。

    ・パスを通そう
     Leopardでは、bashが起動されるとシステムワイドなbashの起動スクリプト(/etc/profile)を実行します。内容を参照すればわかりますが、そこでは/usr/libexecディレクトリにあるpath_helperというシェルスクリプトを呼び出し、PATH環境変数の定義を行っています。
     この設定を変更する場合には、PATH環境変数の再定義を行います。たとえば、/sw/binディレクトリにパスを通す場合は、以下の要領でexportコマンド(環境変数を定義するためのbashの内部コマンド)を実行します。コマンドラインの意味ですが、操作時点のPATH環境変数($PATH)に/sw/binを加えたものをPATH環境変数として定義する、となります。

    - - - - -
    $ export PATH=$PATH:/sw/bin
    - - - - -
    


     このとき注意しなければならないのは、PATH環境変数に列挙した順序のとおりコマンドが検索される、ということです。たとえば、上のコマンドラインを実行したとき、初期設定でパスが通っている/usr/binディレクトリと、後からパスを通した/sw/binディレクトリに同じコマンドが存在する場合、/usr/binのほうが優先されます。反対に、後から追加するディレクトリを最優先にパス
    を通したい場合には、以下の要領でexportコマンドを実行します。

    - - - - -
    $ export PATH=/sw/bin:$PATH
    - - - - -
    


     この設定を常に利用したい場合は、ユーザ別に用意するシェルの起動スクリプトにコマンドラインを書き加えます。bashの場合、ホームディレクトリの「.bash_profile」に書き加えるのが適当でしょう。次回は、この起動スクリプトについて説明したいと思います。

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

    2008-12-09

    目次

    • りんご味Ruby         第37回  藤本 尚邦
    • 藤本裕之のプログラミング夜話   #150
    • 高橋真人の「プログラミング指南」  第148回
    • mosa entranceだより       第2回   エンドウ ヒデオ

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

    真偽値を返すアクセッサを宣言するための(疑似)構文糖衣 attr_predicate を使えるようにする手段として:

     ・クラス継承             – 構文糖衣を実装した親クラスを用意
     ・ミックスインモジュール — 構文糖衣を実装したモジュールを用意
     ・オープンクラス         – Moduleクラスに直接、構文糖衣を実装

    のうち、前回は、クラス継承とミックスインモジュールについて取り上げました。今回はオープンクラスによる方法を見ていきましょう。

    ■ オープンクラス — Moduleクラスに直接、構文糖衣を実装

    Rubyでは既存のクラスを実行時に直接変更することができます。この特徴は、「すべてのクラスはいつでも変更できるように開かれている」という意味で、オープンクラスと呼ばれています。オープンクラスにより、attr_predicate を組込みの attr_reader や attr_writer とまったく同レベルの機能として実装することができます。attr_reader や attr_writer はModuleクラスのインスタンスメソッドなので、attr_predicate も同じようにModuleクラスのインスタンスメソッドとして実装しましょう。

    --------------------------------------- attr_predicate.rb ---
    Module.class_eval do
     def attr_predicate(*names)
       names.each do |name|
         define_method("#{name}?") do
           instance_variable_get("@#{name}") ? true : false
         end
       end
     end
     private :attr_predicate
    end
    ----
    


    クラスに対して、ブロック付きでclass_evalメソッドを呼ぶことにより、既存のクラスに定義を追加・変更することができます。この例では、Moduleクラスにインスタンスメソッドのattr_predicateを追加的に定義しています。このライブラリをロードすると、すべてのクラス定義で attr_predicate を使うことが出来るようになります:

    require 'attr_predicate'
    class TodoItem
     attr_reader    :summary
     attr_predicate :done
     # 以下略
    end
    


    クラス継承とミックスインモジュールによる方法が、能動的にクラス継承したりモジュールを組み込まない限り使えないのに対して、オープンクラスにより直接Moduleクラスを変更する方法では、attr_predicate を定義したライブラリをロードするだけで、どのクラス定義でも attr_reader と同じレベルでattr_predicate を使うことが出来るようになります。

    (補足 — オープンクラスにより直接書き換えてしまう方法は、とくに多数のプログラマが使うケースでは、予期せぬ事態を引き起こしかねないので、乱用しないように注意して使いましょう!)

    ■ ClassクラスとModuleクラス

    ところで、なぜ attr_reader や attr_writer は Moduleクラスのインスタンスメソッドなのでしょうか? これまで、モジュールやクラスとは何か? ということにほとんど触れていませんでした。Rubyでは、Objective-Cと同様に、クラスやモジュールも、あるクラスのインスタンスであり、数値・文字列・配列などと同等に扱うことのできるオブジェクトです。そのことを踏まえた上で、以下に説明していきます。

    Moduleオブジェクト(=Moduleクラスのインスタンス)の主な役割は、メソッドの実装を持つことです。以下のモジュール定義例では、speakerとspeakという2つのメソッドの実装を持つSpeakableというModuleオブジェクトを定義しています:

    --------------------------------------- speakable.rb ---
    module Speakable
     def speaker
       if not defined? @@speaker
         require 'osx/cocoa'
         @@speaker = OSX::NSSpeechSynthesizer.alloc.init
       end
       @@speaker
     end
    
     def speak
       speaker.startSpeakingString(self.inspect)
     end
    end
    ----
    


    Moduleオブジェクトは、それを派生させて新しいモジュールを作ったり、そのインスタンスオブジェクトを生成したりすることはできません。単に、メソッドの実装を持つことができるだけです。そこでClassオブジェクト(=Classクラスのインスタンス)が登場します。Moduleオブジェクトの特徴に、派生クラスを定義する機能やインスタンスを生成する機能を加えたものがClassオブジェクトです。

    このような構成は、ClassクラスがModuleクラスの派生クラスとして定義されていることによっています。Classオブジェクト(=Classクラスのインスタンス)がメソッド定義を持つことが出来るのは、Moduleオブジェクト(=Moduleクラスのインスタンス)としての特徴によるものと見做してもいいでしょう。

    Moduleオブジェクトは、クラスオブジェクトの定義(平たく言うとクラス定義)のとき Module#include を使ってインクルードすることにより、多重継承なしで、メソッドの実装を共有することができるようになっています。あるいは、Object#extend を使うことにより、クラス単位ではなく、任意のオブジェクトに対してだけモジュールを組み込むこともできます。オープンクラスにより、既存のクラスに後からモジュールをインクルードすることもできます。

     require 'speakable'
     Object.class_eval { include Speakable }
    


    とすると、すべてのオブジェクトでspeakメソッドを使うことが出来るようになります:

     12345.speak            # 12345を(英語で)読み上げる
     [1,2,3,"hello"].speak  # 配列の内容を順に読み上げる
    


    話を attr_reader に戻しましょう。Rubyでのメソッド定義には def 構文を使うというのが基本ですが、attr_reader や attr_writer、そして自分で機能追加した attr_predicate は、def構文でメソッドを定義する代わりの手段として、アクセッサメソッドの定義を簡単に記述するために用意された(疑似) 構文と考えることができるでしょう。実際に、attr_predicate の実装では、インスタンスメソッドを定義するためのメソッドdefine_method(これについては次回以降で説明予定)を使ってアクセッサメソッドを定義しています。

    ということで、attr_readerなどの疑似構文は、そのインスタンスがメソッド定義を持つのが特徴であるクラス、つまりModuleクラスのインスタンスメソッドとして実装されているわけです。似たような理由で、モジュールをクラスに組み込むための(疑似)構文糖衣である include やdefine_method などもModuleクラスのインスタンスメソッドとして実装されています(次回に続く)。

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

     前回まで、映画とコンピュータゲームとを比較して得られた結論を簡潔にまとめると、「どちらもその制作(開発)に巨額な費用がかかるが、ヒットしなかった場合のリスクはコンピュータゲームの方が大きい」ということになる。ひらたく言えばいまやコンピュータゲームを作って一発当てようってのは映画製作よりハイリスクな博打だってことだ。

     もちろんコンピュータゲームも映画も、その気になりさえすれば……あ、なるだけぢゃダメか、その気になり、その気を持続することができれば制作費をそれほどかけずに、たとえばたった一人でも作れないわけではない。試しにちょっとそっち方面を考えてみようか?

     まずは映画、実写で出演者が自分一人だけというのはかなり難しいだろうが(難しいというか必然的にアバンギャルドになっちまうような気がする)、アニメを作ると仮定すれば、自分で絵を描いて撮影してちょっと違う絵を描いて撮影してまたちょっと違う絵を描いて撮影してまたまたちょっと違う絵を描いて撮影して……と、確かに大変な作業ではあるが、それでも「鉄腕アトム」の昔と違い、今オレがやったようにコンピュータでコピー&ペーストが使えるのだからかなり楽になってはいる。

     音楽だってGarage bandで作れるし、アニメの声なら全部の登場人物を一人で演じることだって不可能ではあるまい(初期の「サウスパーク」では製作者の1人、トレイ・パーカーがほとんどの登場人物を演じていた)。こう見てくると映画の場合の問題は、制作よりも公開と資金回収のシステムにあるようだ。個人で作った映画なんて普通の配給会社は観てもくれないだろうし、自主上映は多くの場合持ち出しである。

     え、コンテストに出す? それはスジ違いである。というか、ここで考えているのはその制作物でいかにして食って行くかであり、それを足がかりにして(コンテストで認められるなどして)次の仕事を得ることではない、違います。……というか、そういうミチスジしか浮かばないほど個人制作の映像作品をお金にする道は険しいということである。公開するだけだったらYouTubeでもいいんだろうけどね。

     ではコンピュータゲームはどうだろう。一人で制作できるか、と言えばもちろんそれは可能だろう。映画と比較すれば一人でやることによるディスアドヴァンテージは小さいかも知れない。公開だってWebサイトからダウンロード可能にするだけ。簡単だ。代価の回収もベクターなどの料金回収システムを使えばさほどの手間ではない。なんだ、コケたときに将来に渡って全然金が入って来る見込みがないってことさえ我慢すれば道はあるのか……と思いました?

     ちっちっち、でもここまでの話には「一人で金をかけずに制作できる映画あるいはゲーム」のクオリティに関する視点がすっぽり抜けているんだよね。……確かに、プログラマなら誰でも知っているように、コンピュータプログラムのクオリティの高さはそれに関わったスタッフの人数に比例しない。いや、むしろ反比例することさえある(……と、しといてやるが大抵反比例しますよね)。

     だけどコンピュータゲームという商品はもはやプログラムコードだけで構成されているものではないんである。根本にあるゲームのアイディア、コンセプト、シナリオなどは別としても、プレイヤーが目にするインタフェース部分のグラフィックの量はビジネス・アプリケーションの比ではないし、ただ絵があればいいわけではなくて、ゲームの内容により親しみやすかったり可愛らしかったりかっこうよかったり怖かったりしなくてはならない。

     それをまた3Dにして動かすとなると、あのモデリングという……なんつかな、オレのような「面倒くさいことが大嫌いだからプログラマやってる」みたいなニンゲンには「同じコンピュータの前に座ってニンゲンがやる行為とは思われない」ようなちまちまちまちまちまちまちまちました作業が必要になり、またそこに出来不出来が生じてくるし、それがまたゲームのクオリティとして云々されるわけで……。

     早い話、どんなに超人的な努力をしても、今どき一から十まで一人で制作しましたなんてゲームで「一発当てる」ことは不可能に近いのである。確かにオレは前の原稿でテトリスの例を出したけど、逆に言えばテトリス以来ああいう例を知らないでしょ? ちうことは、プログラマがゲームを書いて食って行くってことはとりもなおさずゲームを作るチームの「スタッフの一員」となるってことなんだよね。次回はちょっとその辺を……。
    (以下次回 2008_12_05)                       

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

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

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

     こんにちは、高橋真人です。
     前回の最後で投げかけたテーマは、“値をどこに保存しておくか”ということでした。
     C言語では、変数にスコープという概念があります。これは、「有効範囲」ということを意味しますが、この「有効」の中には二つの要素があります。一つが生存期間、そしてもう一つがアクセス可能範囲です。
     Cにおける変数のスコープには、代表的にはグローバルとローカルの二つがあります。いわゆるグローバル変数とローカル変数です。グローバル変数は、プログラムが動いている間ずっと有効です。つまり、メモリ上に存在し続けます。
     これに対しローカル変数は、その変数が定義されている部分を囲む範囲がその有効範囲となります。一般にローカル変数は関数の先頭で定義されることが多いですが、任意の場所での定義も可能です。簡単なサンプルを見てみましょう。

    01: void foo(void)
    02: {
    03:     int a = foo1();
    04:     if (a % 2 == 0) {
    05:         int b = a * 20;
    06:         ++b;
    07:         foo2(b);
    08:     }
    09:     foo2(a);
    10: }
    


     面白みもない関数ですが、注目していただきたいのは変数のaとbです。これらはいずれもローカル変数ですが、スコープが異なります。aのスコープは関数の実行される間ずっと、ということになります。対してbは、4行目のif文の条件が成立した場合にのみ、存在します。そしてその有効範囲は7行目まで。
     9行目のfoo2(a);の時点ではbはもう存在しませんから、仮にここにfoo2(b);とでも書こうものならば、コンパイル時に「bなんて変数、知りませんよ」と言われてしまいます。
     では、次にちょっとだけ変更してみます。

    01: void foo(void)
    02: {
    03:     int a = foo1();
    04:     if (a % 2 == 0) {
    05:         static int b = a * 20;
    06:         ++b;
    07:         foo2(b);
    08:     }
    09:     foo2(a);
    10: }
    


     どこが変わったか分かりますか? ほんのわずかなところですが、5行目のbの宣言の頭にstaticというのが付きました。
     実は、このコードはCではコンパイルできません。「初期化の要素が定数でないので」と出てしまいます。では何故こんなコードを書いたかと言いますと、C++では問題なくコンパイルが可能だからです。
     ローカル変数にstaticという識別子が付くと、これはただのローカル変数ではなく、静的変数というものになります。静的変数になってもローカルであることに変わりはなく、アクセス可能な範囲としては前の例と同様ですから、やはり9行目でfoo2(b);と書けば、「そんな変数は、知らん!」と言われます。
     しかし生存期間という意味では、7行目で終わることはありません。プログラムが動いている間は存在し続けます。ただし、静的変数がグローバル変数と寿命において異なるのは、「どの時点で生成されるか」です。
     グローバル変数がプログラムのスタート時から終了時まで、ずっと存在し続けるのに対して、静的変数は定義の行われている行、つまり上記のコードでは5行目が最初に実行される時点で生成されます。それはつまり、もしプログラムでこの部分が実行されることがなければ、この変数は生成されないままプログラムの終わりを迎えるということも意味します。
     さて、static識別子が付くことにより起こる変化でさらに興味深いのは、初期化の部分です。変数bの宣言(定義)部分では、

    static int b = a * 20;

    となっています。これは、bが定義されると同時にa * 20の値で中身が初期化されるということを示しています。静的変数における初期化も、他の変数の場合と同様、「変数が生成される時に設定される値」を意味しますから、メモリ上にずっと存在し続けるbという変数の初期化は最初に5行目が実行された時に行われることになります。
     よって、このfoo()という関数が複数回呼び出された場合でも、bの値がa * 20に設定されるのは最初の1回のみです。従って、この関数が呼ばれる度、bは6行目にあるインクリメントの処理によって増加しますから、7行目のfoo2()に渡される値は、1つずつ増えていくのです。仮に、最初のaの値が20であったとすると、bは呼び出されるごとに401、402、403…となっていくという具合です。
      あ、もちろん6行目のコードが実行されるためには4行目の条件が成立しなければなりませんね。とりあえず、毎回aは偶数であるということにしておきます。
     さて、今回の例では、bの初期化に単純な式を使っていますが、この部分が関数の呼び出しになっていても構いません。そうしますと、例えば「最初の一回だけ呼び出される関数」などという仕組みも作ることが可能になります。

     今回のこの静的変数の使い方がこれからの説明で重要になりますので、よく理解しておいてください。

    mosa entranceだより       第2回   エンドウ ヒデオ

    11月25日(火)、第4回 mosa entranceを開催いたしました。うれしいことに前回以上に、多方面からの参加者が増えて来ています。

    前回までお話を伺っていた小池邦人さんが多忙のため、急遽iPhoneアプリ「今日の地震」をリリースされたばかりの、南保さんからお話を伺うことになりました。

    前回までは、メモリ管理やインターフェースビルダーなどプログラミング手法についての内容でしたが、今回はアプリのリリースまでのお話や、「今日の地震」で行なっている、外部サーバとの連携方法など、リリースしたからこそ経験できた貴重なお話を聞かせて頂きました。

    リリース当初、相当なインパクトがあるため、外部サーバからデータ取得を行なう場合、負荷の分散を検討しなければならない点や、リリース後のちょっとした修正に対応できるよう、設定ファイルの持ち方を検討するなど参考になるお話を幾つも頂きました。

    何より驚いたのは、南保さんは学生で、Macユーザになって半年ほどで、iPhoneアプリのリリースまで漕ぎ着けたしまった点に、一同驚きをを隠せませんでした!

    また、毎回終了後に飲み会を行なって親睦を深めている効果もあってか、前回以上に活発で、楽しく時間を過ごすことが出来ました。

    雰囲気そのままお伝えできないのが残念ですが、一人でふらりと突然やって来ても、きっと良い時間を過ごすことができると思いますので、興味をお持ちの方は、是非足をお運びください。

    ◆エンドウ ヒデオさんのプロフィール
    はじめまして、プログラマをしておりますエンドウと申します。小さな会社〜大きな会社までを経験して、現在はフリーで活動しています。開発に携わったシステムは、発電所制御、鉄工所制御、ウエハー検査機、病院内ネットワーク、飲食店向けなど様々な業種で設計、開発を行なってきました。現在はウェブを中心に開発を行なっています。

    なんだか、MacやiPhoneの世界と接点がなさそうな雰囲気ですが、漢字Talk7.5.2の頃から、Macの世界に魅了され現在に至ります。当時はプログラマでも自宅でパソコンを持っている人は少なく、インターネットにやっと接続できるようになった頃で、通信速度同様ゆるやかな時代でした。そんな時代からのMacユーザです。

    Macのアプリケーションを何時かは作ってみたいと思いながらも、だいぶ時間が経ってしまいましたが、iPhone&iPod Touchをきっかけにプログラミングを始めてみようと決心した次第です。

    そうはいっても、日本語化されたドキュメントも整備されていなかったので、なかなか重い腰が上がらなかったのですが、数ヶ月前に、Dashcodeを使えば簡単にiPhoneサイトを作成できることを知りました。自分のためだけに作った稚拙なものでしたが、通常のブラウザで動作するのとは違った、遠い昔に経験したような「アプリケーションが動作した!」という単純なよろこびがありまし
    た。プログラムを作るのが楽しいと思えるなんて何年ぶりだろうと振り返ってしまうほどでした。それからコツコツと機能を増やして公開したところ、びっくりするほど嬉しい反応と感謝の言葉を頂きました。使って頂いた方が、私に気持ちを伝えたくなるなんて、なんだかスゴイことが起きたように思えました。

    「MOSA」の言葉の中には「アーティスト」の意味も込められていますが、これは人に見せて初めて成立することのように思います。使って頂いた方が「ちょっとイイね」と思えるような楽しいもの、誰かのもとに届いて心に響いてくれるようなものは、結局のところ、最初の自分の気持ちに帰結するのかなと思います。ミュージシャン、画家など一般的に言うアーティストのインタビューで、「まず自分が楽しむこと」とよく目にします。全く論理的な言葉ではありませんが、経験を通してそれが全てを言い表しているように今は感じられます。沢山の人に評価されるのはちょっと怖い気もしますが、本当に自分が良いと思えるものならば、自分の気持ちがゆっくりと、沢山の方に浸透していくのかなと感じています。ちょっと遠回りしてiPhoneアプリに着手することになりましたが、また新しい気持ちで、今度はiPhoneアプリを沢山の人に届けたいと思っています。そしてアプリケーションを作る喜びを味わいたいと思っています。

    最後まで読んで頂きまして、ありがとうございました。

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

    2008-12-02

    目次

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

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

      〜「iCalサーバ」編〜

     クライアントからiCalサービスを利用するにはMac OS Xにデフォルトでインストールされている「iCal」を使用するわけですが、LeopardにはiCalサービスをより活用するためのツールとして「ディレクトリ」というユーティリティがバンドルされています。今回はこのツールについて解説します。

    ◇ディレクトリ
     まずこのユーティリティのインストール場所ですが、「/アプリケーション」の「ユーティリティ」フォルダになります。「ディレクトリユーティリティ」というよく似た名前のユーティリティもありますので間違わないように注意してください。
     このユーティリティは単独では動作せず、ディレクトリサーバと連携することで機能します。このため「ディレクトリ」を使用するにはあらかじめクライアントをOpen Directoryのマスター(あるいはレプリカ)に接続しておく必要があります。

     「ディレクトリ」を起動するとOpen Directory上に登録されているユーザおよびグループレコードの一覧が表示されます。またレコードを表示するだけでなく新規に追加したり既存のレコードを編集することもできます。
     レコードの変更を行うには適切なアクセス権が必要になりますので認証が必要になり、デフォルトではKerberosによる認証が行われます。認証方法は環境設定で変更することもできます。というわけで、この「ディレクトリ」というユーティリティを使えばOpen Directory上のレコードを管理することができるのです。
     ユーザアカウントやグループアカウントの管理を行うのであれば「ワークグループマネージャ」を使用すればよいのですが「ディレクトリ」を使用することでiCalサービスで利用可能なデータを管理することができます。例えば会議室やプロジェクタを管理し、iCalサービスで利用することができるのです。
     「ディレクトリ」では次の4種類のデータを管理できます。

    ・個人(Users/People)
    ・グループ(Groups)
    ・場所(Places)
    ・リソース(Resources)
    ※括弧内はOpen Directory上でのレコードの保存場所

     「個人」とはユーザアカウントのことで「ディレクトリ」上でレコードを追加することもできます。ただし「ディレクトリ」で追加するのはログイン可能なユーザアカウントではなくアドレスデータとよばれるレコードになります。あらかじめ「ワークグループマネージャ」や「サーバ環境設定」でユーザアカウントを登録しておけば「ディレクトリ」上では「個人」として参照できます。さらに、ユーザアカウントであれば「マネージャ」や「直属の部下」といった属性も設定でき、企業などでの組織体系を管理することもできます。
     「グループ」は「個人」とは異なり、「ディレクトリ」上で追加したグループはグループアカウントとして登録されます。またメンバーの編集を行うこともできます。
     「場所」を登録しておくと「iCal」でイベントを作成するときの場所として利用できます。「場所」にはマップを設定することもできます。マップを設定するにはあらかじめ「ファイル」>「マップを編集…」メニューからマップを登録しておきます。マップは「場所」だけではなく「個人」や「リソース」にも設定できます。

    ・「場所」へのマップの設定
    http://www.htabata.com/img/MXS105/iCal/Directory_02.png

     イベントの場所として利用するには「ディレクトリ」で「場所」を追加したときに「スケジュール」の設定で予約可能に設定し、カレンダーサーバを指定しておきます。

    ・「場所」のスケジュール設定
    http://www.htabata.com/img/MXS105/iCal/Directory_03.png

     すると「iCal」の「ウインドウ」>「アドレスパネル」メニューからリソースが参照できるようになり、ドラッグ&ドロップでイベントの場所として設定できます。

    ・イベントへの場所の設定
    http://www.htabata.com/img/MXS105/iCal/iCal_test1_03.png

     「リソース」はあらかじめ様々なタイプが用意されており、たとえば社内で共有するような備品の管理に用いることができます。リソースタイプを新たに追加することもできます。

    ・標準で用意されているリソースタイプ
      コピー機、スキャナ、デジタルカメラ、ノートブック
      ビデオカメラ、プリンタ、プロジェクションスクリーン
      プロジェクタ、会議電話、自動車

     このように「ディレクトリ」を使えばiCalサービスをより効果的に活用できるようになります。当然のことですが「場所」や「リソース」はあらかじめ誰かが追加しなければ利用できませんので、実際に利用するには運用面のことも考えておかなければなりません。またこの機能はLeopardで新しく追加されたものであり、残念ながらまだまだ荒削りな部分もありますので導入を検討する
    場合はまずは小規模なグループで試験的に運用を始めてみるのもよいでしょう。
    次回へつづく                             

    小池邦人のCarbon視点でiPhone探求(2008/11/28)

     〜 サンプルは一番身近な先生 〜

    技術ドキュメントを一通り読破したら、次にすべき事は、サンプルソースコードを参照してiPhoneアプリケーションで実現可能なことを正しく認識することだと思います。今回は「iPhone Dev Center」からダウンロードできるサンプルソースコードの内容を詳しく紹介したいと思います。

    現在「iPhone Dev Center」サイトには43のサンプルソースコードが登録されています。それを独断と偏見でカテゴリー別に分類してみました。幾つかのサンプルソースコードは、その機能のため複数のカテゴリーに含まれていますので御注意ください。サンプルソースコードには実機(iPhoneかiPod touch)でしか起動できないものがあります。またアクセレロメータ(加速度センサー)関連の機能は実機でしか動作確認できません。それから、一部のサンプルはWWDC 2008やTechTalk(東京)で提供されたものです。参加された方は、参加者のみ入ることができる閲覧サイトの方を確認してみてください。

    ・3D描画(OpenGL ES)関連

    「GLGravity」シミュレータでは3Dオブジェクトの回転描画を行うデモ
    「GLPaint」OpenGLテクスチャを利用したペイントアプリのデモ
    「GLSprite」OpenGLテクスチャを利用した簡単なスプライトアニメーションデモ

    ・2D描画( Quartz2D)関連

    「QuartzDemo」Quartz2D APIを使う事で可能な2D描画機能のデモ(必見)
    「Reflection」Quartz2D APIでオリジナル画像の下方へ鏡面イメージを描画

    ・テキスト入力関連

    「HelloWorld」キーボードからの簡単なテキスト入力とその表示を行うデモ
    「EditableDetailView」UITableViewでコンテンツ用のテキスト入力を行うデモ

    ・アクセレロメータ(加速度センサー)関連

    「AccelerometerGraph」加速度センサーから得たX,Y,Z要素をグラフ表示するデモ
    「BubbleLevel」加速度センサーを利用した水平器シミュレートのデモアプリ
    「GLGravity」実機ではデバイスの傾きに反応した3Dオブジェクト描画(必見)

    ・オリエンテーション(デバイスの方向)関連

    「WhichWayIsUp」デバイスの回転方向を認識して表示を調整する簡単なサンプル
    「RestaurantViewer」デバイス回転でビューのレイアウトを変更(WWDCで提供)

    ・ロケーション(位置情報)関連

    「LocateMe」現在の位置(GPS)情報を入手するためのCore Location APIのデモ

    ・アニメーション関連

    「MoveMe」Core Animation APIを利用した画像の移動と拡大縮小のデモ
    「ViewTransitions」Core Animation APIを利用したUIViewのトランジションデモ
    「TheElements」UIViewとボタンのフリップ(反転)を試すことができる周期表アプリ
    「Metronome」メトロノーム(針の回転アニメとサウンド)をシミュレートしたデモ
    「SimpleAnimation」非常に簡単なUIViewアニメーションサンプル(WWDCで提供)

    ・オーディオ関連

    「aurioTouch」オーディオ入力と再生をモニタ(オシロスコープ)するデモアプリ
    「oalTouch」Open AL(3D音響効果)APIの機能を試すデモアプリ(実機専用)
    「SpeakHere」Audio ToolBox APIを利用した音声の録音と再生のデモ
    「SysSound」バイブレーションと短いサウンド(5秒以内)の再生を行うデモ
    「Metronome」こちらも短いサウンドの再生方法を確認できるデモアプリ

    ・ビデオ関連

    「MoviePlayer」Medea Player Frameworkを利用した映像(Movie)の再生デモ

    ・ゲーム関連

    「CrashLanding」加速度センサーを用いたロケット着陸ゲーム(何故か登録削除?)
    「TouchFighter2」本格派シューティングゲームサンプル(WWDCやTechTalkで提供)

    ・コントロール関連

    「PageControl」UIScrollViewとUIPageControlの使用方法を解説したデモ
    「UICatalog」iPhoneのGUIに用いられるコントロールやビューの機能一覧(必見)

    ・ビューコントローラ関連

    「DrillDownSave」UINavigationControllerの階層レベルをファイル保存するデモ
    「NavBar」UINavigationControllerとUIViewControllerの利用方法の総合的なデモ
    「SimpleDrillDown」UINavigationController使ったUITableViewの階層表示デモ

    ・テーブルビュー関連

    「TableViewSuite」5段階レベルのサンプルでUITableViewの使い方を解説(必見)
    「Accessory」UITableViewのセル右側に表示されるアクセサリ表示のカスタム
    「EditableDetailView」UITableViewでコンテンツのテキスト入力を行うデモ
    「HeaderFooter」UITableViewのカスタムヘッダーとカスタムフッターのデモ
    「TableSearch」UITableViewのコンテンツサーチ(UISearchBar使用)のデモ
    「TouchCells」UITableViewのカスタムセル(タッチ可能)を実装しているデモ

    ・ビュー関連

    「UICatalog」iPhoneのGUIに用いるコントロールやビューの機能一覧(必見)
    「HeadsUpUI」UIView上にオーバレイ描画を使ったGUIを構築するデモ
    「PageControl」UIScrollViewとUIPageControlの使用方法を解説したデモ
    「Scrolling」画像表示を利用してUIScrollViewの2種類の機能を示したデモ

    ・マルチタッチ関連

    「Touches」マルチタッチで3つのオブジェクトを同時にドラッグ操作するデモ
    「MultiTouchDemo」2本指での画像ピンチ操作(拡大縮小)デモ(WWDCで提供)

    ・データベース(SQLite)関連

    「SQLiteBooks」SQLite APIの利用方法を解説したデーターベースアプリのデモ

    ・ネットワークとインターネット関連

    「SeismicXML」NSXMLParserを使うことでXMLドキュメントをパースするデモ
    「BonjourWeb」ボンジュールによって特定ネットワークサービスを探し出すデモ
    「Reachability」通信は携帯回線かWiFi経由かなどを判断する方法を示したデモ
    「URLCache」ウェブサーバーからの画像ダウンロードとキャッシュ活用のデモ
    「WiTap」ボンジュールとネットサービス&ネットブラウザーを活用するデモ

    ・ユーザーデフォルト(環境設定)関連

    「AppPrefs」名前やテキストカラーなどをアプリケーション環境設定へと保存

    「MoviePlayer」背景色やスケールなどをアプリケーション環境設定へと保存

    ・アプリケーション起動関連

    「LaunchMe」opneURLに定義されたURLを渡して別アプリケーション起動するデモ

    ・セキュリティ関連

    「CryptoExercise」Cryptographic(暗号)APIを利用するデモ(実機専用)
    「GenericKeychain」Keychain(認証)APIを利用するデモ(実機専用)

    サンプルソースコードの確認が終了しましたので、次回からは、さっそくXcodeを利用したiPhoneアプリケーションの開発に取り組みたいと思います。まずは、Xcodeで用意されているテンプレート(雛形)プロジェクトの種類を調べてみることにします。

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

    〜 いま敢えて学ぶTerminalのイロハ(4) 〜

    ・転ばぬ先の「man」
     コマンドは使うものであり、暗記するものではありません。自然に覚えてしまうならともかく、無理にアルファベットのら列を記憶しようなど愚の骨頂、必要なときには調べればいいのです。そんなとき拙著「Mac OS Xターミナルコマンド ポケットリファレンス」があれば言うこと無しですが(笑)、実際のところ「man」さえ覚えておけば十分です。これだけは覚えてください、Online-manualの「man」です。
     manの使い方はシンプルそのもの、知りたいコマンド名を引数に与えればOKです。「ls」というコマンドの用法を知りたければ「man ls」、openコマンドならば「man open」、といった具合です。「man man」とすれば、manの使い方も確認できます。Mac OS Xに収録されているマニュアルはすべて英語ですが、あるとないとでは大違いです。
     manの操作方法ですが、SPACEキーで次ページ、[b]キーで前ページ、[q]キーで終了と、この3つを覚えておけば十分です。上下のカーソルキーも利用できます。[g]キーでマニュアルの先頭ページ、[SHIFT]+[g]キーで最終ページに移動することも、覚えておいて損はありません。

    - - - - -
    $ man open
    - - - - -
    


    ・コマンドを逆引きしよう
     覚えて便利なmanですが、対象とするコマンドを正確に入力する必要があります。コマンド名がわからない、綴りに自信がないといった場合には、なにかしらのキーワード(ただし英語)を指定し、コマンド名を割り出す方法があります。
     キーワードから関連するコマンド名を調べるときには、「-k」オプションを付けてmanを実行します。たとえば、ファイルの複製を行うコマンドを調べたいとき、ファイルは「file」、複製は「copy」ですから、以下の要領でmanを実行すればいいことになります。複数のキーワードを指定する場合、または「Mac OS X」のようにスペースを含むキーワードを使用する場合、両端を
    「’」で囲むことがポイントです。

    - - - - -
    $ man -k 'copy file'
    - - - - -
    


     上記のコマンドラインをLeopardで実行すると、次のような結果が得られるはずです。結果に目を通せば一目瞭然、知りたいコマンドは「cp」だとわかります。

    - - - - -
    CpMac(1), /Developer/Tools/CpMac(1) - copy files preserving metadata and forks
    File::Copy(3pm)          - Copy files or filehandles
    cp(1)                    - copy files
    cpio(1)                  - copy file archives in and out
    - - - - -
    


    ・マニュアルをキーワード検索
     Leopardに収録されているオンラインマニュアルは、すべて英語で記述されているため、読むには体力も必要です。コマンドは基本的に利便性を追求するための道具ですから、知りたい部分だけを効率的に読む、というスタンスのほうが気疲れしません。
     manの検索機能は、マニュアルから特定のキーワードを探すときに便利です。使い方はかんたん、マニュアルを表示した状態で[/]キーを押し、画面左下に表示された「/」に続けてキーワードを入力、[enter]キーを押せばOKです。するとヒットした箇所が反転表示されるので、[n]キーを押して次のヒット位置へ、[SHIFT]-[n]キーで前のヒット位置へ移動という作業を続
    け、目的の情報にたどり着くという流れです。

    ・Linux / FreeBSDの日本語マニュアルは?
     英語の文章に耐性があれば、以上の方法で必要にして十分な情報が得られるはずですが、やはり日本語の文章のほうが理解しやすく、誤読の危険性も減ります。Web上に存在するLinuxやFreeBSDを対象にした「日本語man」を使う、という手も一計でしょう。

    FreeBSD 日本語マニュアル検索
    http://www.jp.freebsd.org/man-jp/search.html

    JM Project
    http://www.linux.or.jp/JM/

     ただし、所詮は異なるOSですので、いくつかの確認事項があります。まず、当たり前ですが、Mac OS X独自のコマンド(open、lipo、otoolなど)は、他のOSをターゲットとしたWebサイトに期待できないこと。これは、Terminalでmanを実行するか、市販の書籍をお読みいただくしかありません。
     lsやcpといった基本的なコマンドは、多くの部分はLinux/FreeBSDで共通していますが、若干の機能差があることに注意が必要です。たとえば、Linuxを対象にしたJM Projectでは、GNU製のlsを対象にしていますが、Leopardに収録されたlsは独自に拡張されているため、デフォルトでの動作やオプションに割り当てられた機能(-vオプションの挙動など)が異なります。
     一方、GNU製のコマンド(tar、gzipなど)は、バージョンの差を除けばすべてのOSで共通です。FreeBSD/Linuxどちらの日本語マニュアルも参考になるので、大いに利用すべきでしょう。

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