MOSA Multi-OS Software Artists

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

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

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

2007-05-29

目次

  • 「りんご味Ruby」       第4回  藤本 尚邦
  • 藤本裕之のプログラミング夜話   #115
  • 高橋真人の「プログラミング指南」  第113回
  • 書籍紹デザイニング・インターフェース 第2版

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

前回は、REPLの基本的な仕組みについて説明しましたが、今回は「RubyのことはRubyに聞け」の続きとして、irbとCocoaRepl.appを紹介します。

■ RubyのことはRubyに聞けその2 – irb

irbは、前回紹介した自作repl.rb、あるいはRubyのサンプルeval.rbに似たタイプのREPLコマンドを大幅に発展させた、Rubyに標準で付属するREPLコマンドです。基本的な使い方は、repl.rbと同様に

・標準入力の終端(コントロール+D)に達しないかぎり、以下を繰り返す:
・プロンプトを表示して
・標準入力から文字列を読み込み
・それを(Rubyプログラムとみなし)評価して
・結果を表示

という流れになりますが、irbの場合には、構文的に正しい(と推定される)Rubyプログラムが完成するまで何行でも入力を受け付け、完成したところで入力されたプログラムが評価されます。そのため、メソッドやクラスの定義、if構文やブロック構文の入力に何行でも費やすことが可能になります。

 $ /usr/bin/irb
 irb(main):001:0> 1 + 2 + 3
 => 6
 irb(main):002:0> puts "hello,world"
 hello,world
 => nil
 irb(main):003:0> Time.now
 => Thu May 24 15:03:17 JST 2007
 irb(main):004:0> def factorial(n)
 irb(main):005:1>   if n == 0 then
 irb(main):006:2*     1
 irb(main):007:2>   else
 irb(main):008:2*     n * factorial(n-1)
 irb(main):009:2>   end
 irb(main):010:1> end
 => nil
 irb(main):011:0> factorial 10
 => 3628800


irbには、この他にもいろいろと隠れた機能が盛り沢山に含まれているようなのですが、私も説明できるほどにはわかっていません(汗)

■ RubyのことはRubyに聞けその3 – CocoaRepl.app

irbはターミナルから使ういわゆるコマンドラインツールなのですが、Macの開発者の中にはコマンドラインツールが苦手な方もいらっしゃるかもしれないということで、Ruby用の簡易的なREPLとしてCocoaRepl.appというアプリケーション(OSX 10.4用ユニバーサルバイナリ)を用意しました。

http://rubycocoa.sourceforge.net/hisa/files/CocoaRepl.app.zip

ここでは、CocoaRepl.appの使い方について簡単に説明します。

CocoaRepl.appを起動すると、ウィンドウが表示されます。このウィンドウの中で上側の部分が、Rubyプログラムを落書きするためのテキストビュー、通称「落書きビュー」になります。下側の部分は、状況に応じて、評価結果が表示されたり、標準出力・エラー出力の内容が表示されたり、Rubyに付属しているリファレンスマニュアルやメソッド名のリストが表示されたりします。

◇ Rubyプログラムの入力

落書きビューの好きなところに、Rubyプログラムを入力します。もちろん複数行でも構いません。メソッドの入力中に、コマンドキーを押しながらピリオドを入れると、メソッド名の候補一覧が表示されます。また、入力中にリファレンスマニュアルを参照し、マッチするエントリーがあれば、それを下側のビューに表示します。

◇ Rubyプログラムの評価・実行

落書きビューに入力したプログラムは、Rubyメニューの中にある3つのコマンド(それぞれショートカットが割り当ててあります)のいずれかを使って評価・実行することができます。評価・実行の結果は、ウィンドウの下側に表示されます。

・Eval — 落書きビュー全体を評価
・Eval Selection — 選択箇所を評価
・Eval Line — 挿入ポイントのある行を評価

(注) Rubyメニューには、挿入ポイントを含むブロックを評価するための
Eval Block というコマンドもありますが、このコマンドは、今のところま
ともに実装されていません。

CocoaRepl.appには、RubyCocoa.frameworkが含まれているので、Cocoaのオブジェクトにアクセスすることも可能です。例えば:

OSX::NSApp.mainWindow.setTitle(Time.now.to_s)

と入力して評価・実行するとどうなるでしょう?

CocoaRepl.appは、落書きをファイルに保存できない・標準入出力の扱いが不完全など、いろいろと機能が足りないのですが、Rubyプログラムのかけらを試してみるくらいの用途にはそれなりに使えます。

■ (宣伝) RubyCocoa 0.11.0

先日、RubyCocoa 0.11.0をリリースいたしました。よろしければお試しください。

http://rubycocoa.sourceforge.net/

上記のCocoaRepl.appも、RubyCocoaを使ってRubyで書かれています。Finderで
CocoaRepl.appのコンテキストメニューから「パッケージの内容を表示」を選び、Contentsフォルダの中にあるResouresフォルダを開くと、Rubyで書かれたCocoaRepl.appのソースファイルがいくつかありますので、興味のある方はのぞいてみてください。

■ まとめ

本連載では、これまでも今後も、随時、Rubyプログラムのかけらが登場するはずです。REPLを使わずに、Rubyプログラムをファイルに保存してrubyコマンドで実行してみるという方法もあるのですが(REPLよりもそちらの方法を好む方もいるようです)、今回紹介したようなREPLに親しんでいただき、手を動かしながらRubyプログラムを試しつつ読んでいただければと思います。

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

 前回の続き、予告通り、作ったMyApplication.h とMyApplication.m の中身のコーディングを行おう。まずヘッダーファイル、MyApplication.hをひらき、以下のようにコーディングする。こりゃなんだ、という疑問はあとで氷解するはずなので(たぶん)、今はだまされたと思ってやってほしい。

#import 

@interface MyApplication : NSApplication {
    AboutWindowManager*      aboutWindowController;
}

-(void)awakeFromNib;
-(IBAction)orderFrontStandardAboutPanel:(id)sender;

@end


 上で足した、「aboutWindowController」というインスタンス変数がMainMenu.nibではない別のnibファイルのオーナーオブジェクトになる。こいつの初期値をnilにしておくために awakeFromNib が必要。そしてorderFrontStandardAboutPanel: は前回「こいつをオーバーライドして別のnibファイルからアバウトパネルをロードする」と書いたメソッドである。あ、ここで一言、これ、このほうが分かりやすいかなと思ってオーバーライドしてるので、このメソッドの名前の意味、すなわち「標準的アバウトパネルを
前面に持ってくる」ちうのと実際の行いが違って気分がすぐれない、というヒトはMainMenu.nibに立ち戻り、この MyApplication クラスに……例えばshowMyAboutPanel: てな名前のアクションを追加し、アプリケーションメニューの「About このアプリケーション」からそいつへラインをつなげても構わない。その場合でも単に「オーバーライド」ではなくなるだけで動作に変わりはないから。

 こんだけやったら次は MyApplication.m の番。これまた意味はあとで判明するので(たぶん)とりあえず以下のようにコーディング。

#import "MyApplication.h"

@implementation MyApplication

-(void)awakeFromNib {
    aboutWindowController = nil;
}

-(IBAction)orderFrontStandardAboutPanel:(id)sender{
    if(aboutWindowController == nil){
         aboutWindowController = [[AboutWindowController alloc]
                                  initWithWindowNibName: @"MyAbout"];
    }
    [aboutWindowController showWindow:self];
}

@end


 awakeFromNib の中身はさっき書いた通り。問題はもうひとつのメソッドだよね。この意味するところは、「aboutWindowController オブジェクトがまだ生成されてなかったら、これをアロケートし、MyAbout.nib というnibファイルの中身を使って初期化しろ。ほんで、そのオブジェクトに showWindow:メッセージを送れ」、である。
 これでこいつのコーディングはおしまい。次回はその、MyAbout.nibを作成する。……そんな馬鹿なと思うかもしれないけどもうこれ以上のコーディングは必要ないのである。ま、モノがアバウトパネルという見せるだけのもんだからだけどね。Cocoaって簡単でしょう?
                            (2007_05_24)

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

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

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

 こんにちは。高橋真人です。
 はじめに訂正です。前回のコードに大きなミスがありました。MyApplicationクラスの関数、HandleNew()とHandleClose()の中身が全く違うものになっていました。正しくは以下の通りです。
 前回のコードをビルドして実際に試された方が戸惑われているだろうとモサ伝の前号にも訂正を載せさせていただきましたが、私としても一体なんでこんな取り違いをしてしまったのかと反省しきりです。
 混乱させてしまった方、すみませんでした。

OSStatus
MyApplication::HandleNew()
{
   PPx::Window* theWindow =
       PPx::NibDecoder::CreateWindowFromNib(
           CFSTR("main"),
           CFSTR("MainWindow"));
   if (theWindow) {
       ::RepositionWindow(
               theWindow->GetSysWindow(),
               nil,
               kWindowCascadeOnMainScreen);
       theWindow->Show();
   }

   return noErr;
}

OSStatus
MyApplication::HandleClose()
{
   OSStatus status = eventNotHandledErr;

   WindowRef theWindow =
       ::GetFrontWindowOfClass(kDocumentWindowClass, true);
   PPx::Window* win = PPx::Window::GetWindowObject(theWindow);
   if (win) {
       win->Close();
   }

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

   return noErr;
}


 それでは気を取り直してコードの解説をいたします。できれば、以下の続きを読まれる前に上記のコードにさしかえた上で再実行してみていただけるとよいでしょう。
 ところで、プログラムを走らせてみて、おかしいと思いませんでしたか?
 MyApplication::HandleClose()という関数(上記のさしかえ部分に含まれています)が呼ばれると、”HandleClose called.”というメッセージがコンソールに出力されるのですが、この出力のタイミングがおかしいのです。メッセージがどのようなタイミングで表示されるのか(つまり、HandleClose()関数がどんなタイミングで呼び出されるのか)について注意しながらプログラムを試してみていただけると「おかしい」の意味がお分かりになると思います。
 この辺についてはのちほど触れたいと思います。

 さて、まずはmain.cpです。
 Setup()という関数ではアプリケーションの初期化をしています。
 ここではSysNibというクラスのオブジェクトを作成していますが、その際にNibファイルの名前を与えています。これは、SysNibクラスのコンストラクタにNibファイル名を与えていることなのですが、こうすることで生成されたオブジェクトが「どのNibファイルを対象にして読み込みをするのか」を記憶するようになります。従って以下に説明するように、単に”MenuBar”と、Nibファイルの中の要素の名前を指定してやるだけでよく、Nibのリファレンスをいちいち生成したりする手間が省けます。
 そんなわけで、作成したSysNibのオブジェクトのSetMenuBar関数を呼び出すと、上で指定したNibファイルの中から、引数で指定した名前を持つメニューバー項目を使って、アプリケーションのメニューバーを構築します。
 メニューに関するコードはこれだけです。

 ところで、SysNibに限らずいろんなところにPPx::というプレフィックス
(接頭辞)が付いていますが、これはPowerPlant Xが定義している名前空間(namespace)です。名前空間に関しては、この連載の第44回で解説していますので、そちらを参照してください。
 それから余談ですが、メモリ管理の話を簡単にします。
 Carbonの経験のある方はメニューの設定などでIBNibRefの変数を使って作業をしたと思いますが、これらの末尾にRefが付く型の変数は使用後にメモリの破棄が必要になることをご存知でしょう。(IBNibRefの場合には、DisposeNibReference()を呼び出す)
 Cを長いことやっていると、こういった後始末をきちんとする習慣(もちろ
ん、よい習慣です)が身に付いていて、コードを見ると、ついつい「メモリ管理がどうなっているのかが気になる」かもしれませんので(笑)、その懸念を払拭しておきます。
 SysNibに限らず、PPxにおいてメモリ管理(確保と破棄)を必要とするケースは、オブジェクト自体がそれをやってくれるようになっています。このようなやり方は、C++の世界ではRAIIなどと呼ばれ、必須の技術となっています。
詳しくは連載の第25回で触れていますので、そちらを参照してください。

 話を戻して、次のRegisterCommonNibDecoders() ですが(以降、特別に強調する場合を除きPPx::は省略します)、これはWindowや各種ViewをNibから読み込むために必要な情報を登録しています。詳しい処理内容については割愛しますが、興味のある方はコードを覗いてみてください。
 ちなみに、Carbonでは、アプリケーションの初期化にはInitCursor()を呼び出すことになっていましたが、最近Appleのドキュメントを読んだら「もはや、不要」と書いてありましたので、呼び出していません。

ニュース解説

★★★ 開発関連のニュースはweb掲載開始しました ★★★
http://www.mosa.gr.jp/?page_id=1017

・四月のニュース
http://www.mosa.gr.jp/?p=1076

書籍紹介               デザイニング・インターフェース

 解説担当:高橋政明

デザイニング・インターフェース
  Jenifer Tidwell 著
  ソシオメディア株式会社 監訳  浅野 紀予 訳
  オライリー・ジャパン ISBN978-4-87311-316-6  定価3,990円

 ユーザーインターフェース(以下UI)に関する今年出版された本で、副題は「パターンによる実践的インタラクションデザイン」です。ソフトウェアに限らず『デザイン上の問題点に対するすぐに使えるパターン集』とありましたので多いに期待して購入しました。

 パターンには連番が振られ全部で94載っています、出版社のwebで目次をご覧ください。各「パターン」は概要、利用場面、理由、用法、事例が解説されています。ヒントや注意点も書かれていて参考になります。
 全ページカラーで美しい本です。原著が2005年ですので画面等をキャプチャしているOSやソフトウェアのバージョンは当時のものです。

 二段組みの部分を除き一行の文字数が多く私には読みにくいと感じました。訳すと文章が長くなるためなのでしょうか。ページ数イコールコストでしょうから難しい判断だったのかもしれませんが、デザインを論ずる本の紙面としては残念です。出版社のwebで原著にもリンクしていて同じ部分をpdfサンプルで見る事ができますのでご自身で確かめてください。

 UIの設計が大変難しいことは皆さん実感されていると思います。それは「使い易くて美しく、それだけではなくすぐにわかる独自性も必要」と要求が高いからでしょう。Interface BuilderでAquaのUI部品をガイドに添ってレイアウトするとそこそこ使い易く美しい画面ができあがります。しかしそれだけでは個性は出せません。ひと目見てそれとわかる個性も製品の大切な要素です。個性を出すためのトレードオフがあるなら、それを最小にするためにも本書の関連するパターンそれぞれに対する理解が大切と思います。

 この本はどのようなUIにするべきか悩んだり行き詰まったりした時の簡便な解決策が書かれている訳ではありません。またUIのチェックリストでもない事は序章にも書かれています。ボリュームのある本ですし即効性は期待しないほうが良いと思います。(実のところ私もまだすべてを読み終えていません)

 UIは様々な条件を考慮しなければなりません。機能が多く大規模なUIの場合、UIのパターンを統一するべきかそれぞれに最適なものを採用するべきでしょうか? おそらく誰が使うか、どのような頻度で使うかの条件だけでも結論は様々と思います。
 本書をとおしてUIのパターンをより理解する事でUI設計時の洞察が深くなるだけでなく、客観的なUIの評価分析にも役立つことと思います。

▼出版社のweb(詳しい目次とpdfのサンプルページが載っています)
http://www.oreilly.co.jp/books/9784873113166/

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