2007-07-03
目次
りんご味Ruby 第6回 藤本 尚邦
初回で、「実践的な内容を織り交ぜながら」と書いたにもかかわらず、細かい話が続いてしまいました。そこで、今回は、簡単だけど応用ができそうな実例を示すことにします。初回に示した、MOSAのRSSを取得して内容を出力するプログラム:
----------------------------------------------- rss-reader.rb ---
require 'rss/2.0'
require 'open-uri'
url = 'http://www.mosa.gr.jp/?feed=rss2'
rss = open(url) { |io| RSS::Parser.parse(io.read, false) }
puts "-- #{rss.channel.title} (#{rss.items.size} entries) --"
puts
rss.items.each { |item| puts item.title }
-----------------------------------------------
これをCGIプログラムに改造してみましょう。
■ 最も単純なRSSリーダーCGIプログラム
----------------------------------------------- rss-reader.cgi ---
#!/usr/bin/ruby -Ku
require 'rss/2.0'
require 'open-uri'
url = 'http://www.mosa.gr.jp/?feed=rss2'
rss = open(url) { |io| RSS::Parser.parse(io.read, false) }
puts "Content-Type: text/html"
puts
puts "
#{rss.channel.title} (#{rss.items.size} articles)
"
puts ""
rss.items.each { |item| puts "
"
-----------------------------------------------
元のプログラムとほとんど同じですね。しかし、これでも立派なCGIプログラムです。違いは以下の通りです:
・1行目にこのプログラムを実行するためのコマンド(ruby)を指定 (一般にこの行のことをshebang行と呼びます)
・HTTPヘッダを出力
・HTTPのヘッダ部とホディ部を区切る空行を出力
・rssの内容をHTMLタグで装飾したHTMLをHTTPボディとして出力
このファイルを /Library/WebServer/CGI-Executables/ の中にrss-reader.cgi という名前で保存してください。さらに、ターミナル上でchmodコマンドを使って実行可能にします。
$ chmod +x /Library/WebServer/CGI-Executables/rss-reader.cgi
まずはターミナル上で実行してみましょう。次のように出力されればOKです。
-------------------------------------------------- (Terminal) ---
$ /Library/WebServer/CGI-Executables/rss-reader.cgi
Content-Type: text/html
特定非営利活動法人MOSA (10 articles)
--------------------------------------------------
それでは、CGIプログラムとして実行してみましょう。まず、パーソナルWeb共有を有効にする必要があります。システム環境設定を起動して「共有」パネルを表示してください。「サービス」タブを選択して、「パーソナルWeb共有」のチェックボックスをチェックしてください。
これで準備は整いました。SafariなどのWebブラウザで、以下のURLを入力してください。
http://localhost/cgi-bin/rss-reader.cgi
うまく表示できたでしょうか? これがもっとも単純なRubyによるRSSリーダCGIです。putsを使ってHTMLを出力しています。単純なうちはともかく、複雑なHTMLを出力するためにはいろいろ工夫が必要そうですね。
■ プログラム本体と表示データを切り分けたCGIプログラム
次は、ひと味違った方法を紹介しましょう。Rubyに付属するERBというライブラリを利用して、プログラム本体と表示用のHTMLデータを分離して、見通しを良くします。
--------------------------------------------- rss-reader-erb.cgi ---
#!/usr/bin/ruby -Ku
require 'rss/2.0'
require 'open-uri'
require 'erb'
url = 'http://www.mosa.gr.jp/?feed=rss2'
rss = open(url) { |io| RSS::Parser.parse(io.read, false) }
puts "Content-Type: text/html"
puts
puts ERB.new(DATA.read).result
__END__
<%= rss.channel.title %> (<%= rss.items.size %> articles)
<% rss.items.each { |item| %>
--------------------------------------------- rss-reader-erb.cgi ---
このプログラムを、前のCGIプログラムのときと同様に/Library/WebServer/CGI-Executables/ の中に保存して(ここではrss-reader-erb.cgiと名づけました)、chmodコマンドで実行可能にします。
$ chmod +x /Library/WebServer/CGI-Executables/rss-reader-erb.cgi
さきほどと同じように、ターミナルで確認してみて、それからWebブラウザで結果を確認してみてください。
このプログラムは、途中の__END__を境に、上側がRubyプログラム、下側はHTMLのような表示用のデータになっています。下側のデータは、Rubyに付属するERBというライブラリを使って、取得したRSSデータを埋め込んだ実際のHTML文字列に変換して出力しています。
puts ERB.new(DATA.read).result
ERBの基本的な役割は、入力文字列の中に埋め込まれたRubyプログラムを実行して、その結果を、入力文字列中に埋め込んで出力することです。PHPをご存知の方であれば、イメージしやすいかもしれません。
-------------------------------------------------- (Terminal) ---
$ irb --simple-prompt
require 'erb'
=> true
ERB.new("hello").result
=> "hello"
ERB.new("hello at <%= Time.now %> ...").result
=> "hello at Thu Jun 28 21:52:17 JST 2007 ..."
ERB.new("<% 10.times {|i| %><%= i %>, <% } %>").result
=> "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
--------------------------------------------------
Rubyプログラムは <% ... %> もしくは <%= ... %> のように囲んで埋め込みます。<%...%>は、Rubyプログラムとして実行後、出力から取り除かれます。<%=...%>は、Rubyプログラムとして実行した結果を文字列として置き換えます。その他の部分は、そのまま出力されます。
__END__については、Ruby言語の仕様として、__END__行以降、Rubyプログラムではなくデータとして扱うことができるようになっています。
DATA.read # __END__以下の行を文字列として返す
今回は、RSSリーダプログラムを、CGIプログラムにアレンジする方法を2つご紹介してみました。
藤本裕之のプログラミング夜話 #117
予告通り,「ビューの中身だけを別のnibファイルから読み込む」という話である。
実を言うと前回までの説明で,インタフェースに関わるリソースを複数のnibファイルに分割する,という話は終わったつもりでいたのであるが,「次はなにをネタにしましょうかねぇ」というメールをタカハシ編集長に出すと,折り返し「サブビューの中身を別 nibファイルに持つというケースについても解説してよ。特にそんなかに配置されたコントロールからどうやってアクションを受け取るとか」というリクエスト。
なぁるほど,それはワタシも今までやってみたことありませんでしたわ,というわけで早速ちゃちゃっと試してみた。以下の説明,自分で作ってみれば簡単なんだけど,なにしろメールマガジンでは図が使えないので,読むだけで解ろうという横着な人には多少回りくどくなることだけ,ご了承いただきたい。
作ってみたのは次のようなプログラム。
起動すると一つのウィンドウが開き,その中にはタブビューが1個ある。タブビューにはタブが2個(仮に「base」と「alternative」とする)あって,初期状態では「base」が選ばれている。そのときのタブビューの表示は「こいつはこのタブビューのbaseタブの中身だぜ」というもの。
ここまで観てきた全てのリソースは,起動と同時に読み込まれる「MainMenu.nib」に定義されている。これから何をしたいかというと,もう1つのタブ,「alternative」を押されたときにこのタブビューの内部に表示されるべきビューの内容を MainMenu.nib とは別の nibファイルとして作成・保存したいわけである。もちろんそのビューにはボタンとかのコントロールがあり,そいつらからのアクションはこのアプリケーションのプリンシパル・クラスで処理できるようにしたい……編集長,リクエストはこれで間違いないよ
ね?
まずは当然ながら Interface Builderを起動する。出てきた「StartingPoints」というウインドウのリストから「Cocoaのビュー」というの……はないのでさぁどうしましょう。まず上のようなことを考えた人が最初につまずくのはここぢゃないかと思う。「なんだ,ビュー単位で nibファイル作ることできねぇんぢゃん。編集長,それ,できませんわ」と,メールなどしているようではいけない。
ここは前回まで,アバウトパネルを作ったときと同じように,「Window」を選んでしまえばいいのである。なぜか? 簡単なことでしょうが。ウインドウがひとつあれば必ずその中身としてビューが1個,あるやないの。別に nibファイルをウインドウ単位で分割したからって,そのまま使わなくちゃならないってことはないんだよね。
この nib ファイルのウインドウの中身に,「こいつはこのタブビューのalternative タブの中身だぜ」という文字列と,それからコントロールのサンプルとしてボタンなどを配置する。続いてこれまたアバウトパネルの時と同じように File’s Owner のクラスを定義する。名前はなんでもいいが,MyTabViewController としておいた。
Interface Builderでソースのスケルトンを作らせ,このnibファイル「TabView.nib」という名前で保存してできあがり……ではないので注意。
このビューをあたかも MainMenu.nib に定義されたもののごとく扱うにあたっては2個ほど問題がある。まず一個は,当然ながらnib に定義されたWindowごとではなくそっから中身のビューだけ引っ張り出してMainのタブビューで表示できるようにすること。もう一個は,このビューに乗っかってるコントロール,つまりボタンを押されたとかスライダーが動かされたとかいうアクションをプリンシパル・クラスでハンドルできるようにすることである。
では最初の課題のほうから。これは以前,この連載で書いた,不定形な(あるいはタイトルバーのない)ウインドウを出しましょう,というやつの応用で,MyApplication.hにコントローラのインスタンス変数を次のように定義し,
MyTabViewController* tabViewController;
MyApplication.m(このクラスはタブビューのdelegateになってる)にタブビューのタブがクリックされたときに呼ばれるメソッド,tabView:didSelectTabViewItem: を書けばいい。
-(void)tabView:(NSTabView*)tabView didSelectTabViewItem:(NSTabViewItem*)tabViewItem {
NSString* identifier = [tabViewItem identifier];
if([identifier isEqualToString:@"2"]){
if(tabViewController == nil){
tabViewController = [[MyTabViewController alloc]
initWithWindowNibName: @"TabView"];
[tabViewItem setView:[[tabViewController window] contentView]];
}
}
}
クリックされたタブの identifierをチェックし,2番目すなわち別のnibファイルから読むほうだったら必要に応じて tabViewController を初期化し,その window のcontentView だけ持ってきて(気分は「横取りして」つう感じだが)それをタブビューアイテムにセットしてしまう。簡単でしょ。では次回はもう一つの課題,いかにしてこのビュー上のアクションをこっちのクラスに持ってくるか……ここまで来ればもう答えは分かったようなもんだと思うが……分かんない人は次回を待たれよ。
(2007_06_29)
高橋真人の「プログラミング指南」第115回
〜番外編・Carbonの将来は?〜
こんにちは。高橋真人です。
今回は、PowerPlant Xの解説を続ける前に触れておきたいことがあります。それは、「Carbonの今後」ということについてです。
今年のWWDCの基調講演で、64bit Cocoaという言葉があったのに64bitCarbonという言葉がなかったということについて、「これは意図的になされたものなのか?」との疑問がApple主催のCarbon-devメーリングリストで提示されました。
仮にそれについての詳細がその後のいずれかのWWDCのセッションにおいて語られたとしても、基調講演以外のすべてのセッションはNDAの下に保護されているため、WWDCの参加者からそれらが語られることはありません。Carbon-devメーリングリストは原則的に公開のものですから、ここでNDAベースの話が行われることはないわけです。
ところがAppleの、しかもCarbon関連の技術者であるEric Schlegel氏があっさりと「認めて」しまったのです。ここ数年WWDCでCarbonの動向に関心を持ってセッションを受けていた私の印象では、このSchlegel氏は実質的なCarbonチームのリーダーであるというものでしたので、彼の職責上の発言の重みがどれくらいのものなのかはさておいても、彼の発言は信用に足るものだと私は思います。(*注)
そんなわけで、公開のメーリングリストからでも、Carbonの今後を知るための情報が収集できるのです。
まずは、くだんのメーリングリストのアーカイブが以下のサイトから閲覧できますので、興味のある方は是非ご覧になってみてください。 特に、
http://lists.apple.com/archives/Carbon-dev/2007/Jun/thrd3.htmlのいちばん下の「64-bit Carbon」と、
http://lists.apple.com/archives/Carbon-dev/2007/Jun/thrd4.htmlの下の方にある「Is Carbon Viable?」から始まるスレッドがこのテーマに関する中心的なものです。
もっとも、これらは今でも続く膨大なスレッドであり、なおかつ内容は当然英語ですから、そうやすやすと読む気にもなれない方も少なくないでしょう。
そんな方には、こちらも英語ですが、メーリングリストの参加メンバーの一人がまとめたWikiが以下にありますので、こちらを読むだけでもエッセンスは汲み取れるかもしれません。
http://www.carbondev.com/site/?page=64-bit+Carbon
さて、以下は私自身の個人的な見解です。当然私は、何らの権限もありませんし、保証することもできませんが、私自身が今までCarbon+PowerPlant Xで仕事をしてきた人間として今後どうして行こうとしているのかを知ることを通して、皆さんお一人お一人がご自分なりの今後の方針を立てる上での参考にしていただければと思います。
まず、AppleがMac OS Xの発売当初からCocoaを前面に出して推進してきていることは、今Macの開発に関心を持っている方であれば当然ご存知のことです。もともとMac OS 9以前のToolboxベースのシステムからの移行環境として提供されたのがCarbonの成り立ちですから、完全にMac OS Xへの移行を済ませてしまった方々から「もはやCarbonは不要」という声を上がるのも無理のないことです。
しかしながら、Mac OS X上で実際に開発の仕事をされている皆さんならばお分かりのように、Mac OS XというOSは実に様々なシステムが連携し合いながら動いているシステムです。その他のシステムは言うに及ばず、CarbonとCocoaの境目だって、口で言うほど明確なものではないのです。
例えば私は、「郷に入っては郷に従え」をプログラミングに関しては徹底したい人間で、いざCocoaでプログラムを組もうとした場合には、極力Application KitとFoundation Kitに属するものだけで処理したいと考えるのですが、実際のプログラムを組む上でそれはほぼ不可能です。
つまり、Cocoaと言うとイメージとして、Objective-Cのメッセージ構文である
[object message];
や
[object message:arg1 with:arg2];
のような形の記述が目立ちますが、実際のCocoaのコードには普通のC言語の形式の関数呼び出しも頻繁に登場します。
AppleがCocoaを推進し、さらに既存のC/C++デベロッパ、さらには他のプラットホーム上で開発をしているデベロッパに対して「あなたのC/C++のコードは、そのままObjective-C/Objective-C++のコードでもあるのだ」というようなことを言う人もいます。
しかし、物事はそんなに単純ではありません。コードの問題のみならず、多くの過去の資産をCocoaで使うためには、「そのまま」で済まないケースはたくさんあるはずだ、ということを今までもずっと多くの人が言ってきたわけです。
しかし、Appleがここに来て打ち出した一つの方策は、いろいろ理由を付けてCocoaに取り組もうとしないデベロッパたちの最後の砦を崩しにかかってきたことを意味すると私には思えます。
恐らく、いちばんCocoa化が難しいのは、マルチプラットホームのプロダクトでしょう。中でもMicrosoftとAdobeという二大ソフトウエアメーカーがMacプロダクトのすべてをCocoaベースで作ることができるかということは、他のデベロッパに対しても説得力という意味で大きな影響を持つことは間違いありません。
今回のAppleの動きは、とりあえずはしごを外してみて、屋根の上にいる人たちがどするのかをしばらく見てみようということなのではないかと思います。(屋根の上にはAppleの社員も残っているみたいですが・笑)
つまり屋根の上のデベロッパには、一度「もう後戻りはできないのだ」と腹をくくってもらった上で真剣にCocoaに取り組んでもらう、と。
それでも、もしどうにも立ち行かないというケースが出てきた場合、はしごを外しっぱなしにしておくかどうかは、まだ決まっていないような気がしないでもありません。
実は、今回のAppleの動きを感じる前に、私自身は「とりあえず、軸足をCocoaに移してみようか」と思っていたのです。それは、OSのバージョンが上がるに連れて「Cocoaでしかできない機能」が確実に増えてきていること。特にLeopardで提供されるCore Animationは、将来的に世の中のパソコンの使い方すら変化させてしまう可能性を秘めた技術だと期待しているため、こういったMac OS Xの先進機能を積極的に取り入れて利用していくためにはCocoaを使うことは必須だと思っているからです。
ところで、これまで解説を続けてきたPowerPlant Xはどうするのかということですが、まだ諦める予定はありません。今回WWDCに参加して、あくまで個人的に感じたのですが、世界にはC++プログラマはまだたくさんいるようなのです。
ことコンピュータに関しても、新しいものが出てくると一斉に飛びつき、それまでのものを何のためらいもなく捨ててしまうことの多い日本とは違って、欧米の文化は古いものも大切に使っていく傾向があるように思います。
進化が止まり、価値のうすれてしまったものにいつまでも執着し続けるのもどうかとは思いますが、少なくともC++という言語は現在も活発に機能強化が行われている言語です。
PowerPlant X自体の進化は余り望めませんが、既存のC/C++の資産をCocoaに積極的に取り込んでいく上で、PPxの活用の余地は充分あるのではないかというのが今の私の考え方です。
今後は、その観点で、いかにスムーズかつスマートに融合できるかを模索していきたいと思っています。
【注記】その後に同氏から投稿されたメッセージによれば、「Appleからの公式見解はWWDCにおけるスティーブの基調講演と、私やAppleのDRの人間によるこのMLへの投稿だけだ」とのことでしたので、彼の個人的見解ということではないようです。
書籍紹介 エンジニアのための英会話超克服テキスト
解説担当:高橋政明
エンジニアのための英会話超克服テキスト
-実戦!テクニカル・ミーティング-
平井 通宏 フランシス J. クディラ 共著
オーム社 ISBN 4-274-19735-2 定価2,520円
タイトルが示すように我々技術者に役立つ英会話本です。(書店では技術系の書棚ではなく語学の書棚に置かれることが多いようです)
実はWWDCに向け同じ著者の別の本を入手したのですが、この本の存在を知りこちらを読み始めました。読み始めたのが遅かった事もあり残念ながらWWDCへ向かう時点でまだ半分も読み進んでいませんでした(失敗!)
およそ三年前に初版が出たので最新ではありませんが、電子メールについても解説されていて直接英語で話す場合に限らず役立つと思います。
第I部基礎編と第II部応用編に分かれています。基礎編は基本的表現が分類されていて必要な部分をすぐに参照できるよう工夫された構成です。会議での英会話が中心ですがWWDCのラボような一対一の会話に必要な情報もあります。
特に「第I部9 円滑にコミュニケーションする」では「相手の言った事に反応を示す」や「相手の言葉を理解した/しなかったことを表明する」といった項目が目次に載っています。「英語能力の不足を宣言する」は(私には)有用な情報で今回のWWDCでも役に立ちました〔^_^;〕
文化の違いや技術的な表現について、何を言うべきか、どうすべきか、なぜそうすべきかが解説されています。フォーマルな表現とインフォーマルな表現は記号で明確に示されています。WWDCあるいは相手がAppleの技術者であればインフォーマルな表現でもほとんど問題ないと思いますが使い分けることができるにこした事はありません。
基礎編は自己紹介からはじまっています。職位の英和対応表もあり口頭での自己紹介だけなく英文の名刺を作る場合等にも役立ちそうです。
多数の例文が掲載されています。それぞれどのような印象を与える言い回しかも解説されているので、どの例文を採用するか検討する際に有用です。またコラムには著者の経験に基づくベテランならではのひとことが載っています。(著者の一人は日立製作所に30年間在籍された方だそうです)
付録1にはagendaや議事録の文書化などを含む「技術打合せに関する実務上のポイント」が、付録2にはボキャブラリ索引があります。このように全体に仕事ですぐに使えるよう考えられた内容です。
文化の違いを認識しあうことはコミュニケーションには重要ですよね。今年のWWDCは本書のおかげで少しは安心感を持って臨む事ができました。WWDCのように旅行英語だけでは不足を感じる場合や、英語でemailを書かなければならない場面で本書の情報が役にたつと思います。
▼出版社のweb(少し古い本なので詳細目次はありません)
https://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=4-274-19735-2
◇MOSAからのお知らせと編集後記は割愛します◇