MOSA Multi-OS Software Artists

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

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

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

2009-04-14

目次

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

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

引き続き、Ruby+RubyCocoaを使って「CoreGraphicsによるPDFの描画」を記述するための簡易言語(DSL)を作っていきます。

前回、正規表現オブジェクトのメソッド Regexp#match を使ったパターンマッチにより、RubyCocoaで使うことのできるObjective-Cの関数名の中から、描画コンテキスト(CGContext または CGPDFContext) を操作する関数の名前を見つけて、それを元にしたメソッド名とともに methodnize に渡す手順を作りました:

【編集部注:以下バックスラッシュを¥で置き換えて表現します】

 

  def context_type(type)
     pattern = /¥ACG#{type}Context(.*)¥Z/
     OSX.methods.each do |func_name|
       matched = pattern.match(func_name)
       methodnize(func_name, matched[1]) if matched
     end
   end


例えば、”CGContextFillRect” というCoreGraphicsの関数名がマッチしたときには、methodnize(“CGContextFillRect”, “FillRect”) が実行されます。

methodnize の役割は、引数として渡された名前のCoreGraphicsの関数を呼び出す CGContextクラス(または派生クラスのCGPDFContextクラス) のインスタンスメソッドを生成することです。methodnize の実装を見ていきましょう:

 

  def methodnize(original_name, name)
     method_name = name[0,1].downcase + name[1..-1]
     define_method(method_name) do |*args|
       OSX.__send__(original_name, @context, *args)
     end
   end


■ メソッド名の生成

Rubyでは、メソッド名の最初の文字を英語のアルファベット小文字にすることになっています(注: 実際には、Rubyの処理系によりますが、大文字で始まる名前や日本語のメソッド名も定義できてしまいます)。

methodnize本体の1行目で、引数nameの値から:

   name[0,1].downcase   # 1文字目のみからなる部分文字列を小文字化
   name[1..-1]          # 2文字目から末尾までの部分文字列


を作り、この2つの文字列を + で連結して小文字で始まるメソッド名を作っています。CGContextFillRect の場合には fillRect というメソッド名になります。

ちなみに Webアプリケーションフレームワークの Ruby on Rails に含まれている ActiveSupport というライブラリでは、文字列クラスを拡張しまくって、よくあるネーミング規約 (CamelCase、”_” でつなぐスタイルなど)や英単語名詞の単数形・複数形などを相互に変換する便利メソッドがたくさん追加されています:

◇ (補足) + もメソッド

部分文字列の連結に使った + は、普通の2項演算子のように見えるかもしれませんが、左辺=レシーバで右辺=実引数なメソッドの呼び出しになります。つまり:

 左辺 + 右辺

 左辺.+(右辺)

と同じことなのです。もちろん -, *, / についても同様です。methodnizeで使われている + の左辺は文字列ですから、String#+ が呼ばれることになります。

■ CoreGraphics関数のインスタンスメソッド化

メソッド名ができたので、define_method を使ってインスタンスメソッドを動的に定義します。生成するメソッドの本体では渡された関数を呼び出します。

     define_method(method_name) do |*args|
       OSX.__send__(original_name, @context, *args)
     end


RubyCocoaでは、Objective-C の関数を OSXモジュールのメソッドとして呼び出すようになっています(注: MacRubyの場合は、Kernelクラスのメソッドとして、直接呼び出せるようになっています)。例えば CGContextFillRect なら

 OSX.CGContextFillRect(@context, *args)

という形で呼び出すことになります。ですが、define_method の本体を実装している段階では、どの関数を呼び出すのかが決まっていないので、上記のように直接呼び出すことはできません。そこで Object#__send__ というメソッドを使います。__send__ は、レシーバに対して、第1引数で指定された名前(文字列またはシンボル)のインスタンスメソッドを第2引数以降で渡された実引数とともに呼び出します:

 OSX.__send__("CGContextFillRect", @context, *args)

Ruby の Object#__send__ は、Objective-C での NSObjectプロトコルのインスタンスメソッドの performSelector: や performSelector:withObject: に近いかもしれません。

以上で、CGContextクラスとCGPDFContextクラスの根幹部分はほぼ完成しました。もともとの目標は:

PDFDrawer.file "circle.pdf", [0, 0, 612, 792] do |pdf|
 pdf.page do
   pdf.setRGBFillColor(1.0, 0.0, 0.0, 1.0)
   pdf.addArc(300, 300, 100, 0, 2 * Math::PI, 1)
   pdf.fillPath
 end
end


のようにPDF描画を記述できる簡易言語を作成することでした(第42回)。ということで次回は、PDFDrawer.file と pdf.page の中身を実装します。

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

 1989年12月、突然東京上空で「パチン」と軽い音がしてバブルが弾けた……てな説明でいいんだったら楽なのだが事実はそう単純ではない。これを読んでいるヒトの中には「何を今更そんな分かりきったことを」とおっしゃる方もおられると思うが、経済に不案内で「バブルっていったい何だったの?」と思ってるヒトも少なくはないと思うので一応基本的なことをおさらいしておく。

 ここでいうバブルとは、単純に言えば「実質的にはそんな価値がないものを皆が高い価格で買うことによって生まれる好景気」のことである。80年代末のバブルの主役は主に土地だった。「土地は値下がりしない」ってな言葉、記憶にあるでしょ? でも、土地であろうがなんであろうが価格のついているものが「値下がりしない」のはつまるところ「もっと高くても買うヒトがいるから」である。従って「もう誰も買えない」ところまで値上がりすると必然的に売買はされなくなっちゃうのね。

 でもそれを買っているヒト達は「土地が好きで好きでたまんなくてとにかく持っていたい」というヒト達ではない。「誰かにもっと高く売るために買った」ヒト達で、しかもそれを買うために借金までしてる。土地は高く売れなくても借金の利子は払わなければならない。百歩譲って自己資金で買ったとしても土地というモノは持っているだけで税金もかかる。その損をぜんぶひっかぶらなければならない。早い話バブル経済というのは莫大な金を賭けてプレイするババ抜きみたいなものなのだ。

 1989年の12月、そういう「借金して買った土地を高く買ってくれるヒト(カモとも言う)」というのを探すのが難しくなってきた時に、日銀が金融の引き締めというのをやった。つまり公定歩合を引き上げて借金の利子を高くしたわけ。これでなおさらカモになるヒトはいなくなり、つまり「そんときババを持ってたヤツの負け」が確定したわけ。

 2007年の映画「バブルへGO! タイムマシンはドラム式」ではこの金融引き締めに続く翌年3月の総量規制(不動産融資の伸び率の抑制)がバブル崩壊を招いた、という解釈をしていたけど、それぢゃあのまま野放図にやってりゃうまくいったかといえばそんなことはありえない。確かにこの政策はハードランディング……というより不時着に近いもんだったけれど、成層圏まで舞い上がってから墜落するよりはナンボかましだったという考え方もあるわけ。

 とまぁこういう経緯でバブルは弾け、明るみに出て皆がオドロイたのは、表立って不動産売買を仕事にしているわけぢゃない企業の多くが土地に投資して大損こいてたこと。有り体に言えば「なんで土地バブルが弾けてお前んとこが傾くんだよ」というような企業がグラグラと傾き、社員の新規採用を控えたり事業規模を縮小したりし、土地バブルではたいしていい目も見なかったソフト
ウェア・エンジニアたちに悪影響が……つまりは仕事が減ったのである。

 差し障りがあるかも知れないので具体的な企業名は出さないが、当時ある企業の課長級のヒトと交わした以下のような会話を覚えている。

課長「上が『バブルのときに採用した社員が山ほどいるのに何で外注が要るんだ』って言うんですよ」
オレ「いるなら彼らにやらせればいいぢゃないですか?」
課長「やらせて出来るならやらせてますよ。だいたいワタシが採用したわけぢゃないのに、スキルもない連中いきなりあてがわれてこいつら使えって言われてもねぇ」
オレ「なるほど」

 社内でヒトを育てない、育てる必要がない状況から一転、その育ってない連中を使って仕事をこなさなければならなくなったわけである。でも営業とか経理とかならともかく(そういう業種もそうなのかも知れないけどさ)ソフトウェア開発のスキルは一朝一夕でなんとかなるもんでもない。しかし外の人間を雇う予算もない。当然、開発仕事は必要最小限に絞り込むことになった。

 そんなこんなで90年代の前半、いわゆる「派遣のプログラマ」の地位は目に見えて下がり始める。「高度で専門的な知識を必要とする仕事」でありながらその需要が枯渇しちゃったのね。そして94〜95年、いよいよ「インターネット」がシーンに登場するわけなんだが……。
(以下次回 2009_04_10)

                       

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

これから始めようとする人へ(7)

 皆さんこんにちは、高橋真人です。
 さて、前回のObjective-Cについてのお話は、あくまで言語的な側面から見たものです。Objective-Cの言語仕様は確かに見た目においても独特なものなので、そのこと自体にも説明する価値はあるかもしれません。
 ただ、実際のプログラムを書く上においてはCocoaフレームワークの提供する機能を使わないことはまずあり得ないと言えるでしょう。また、Objective-Cの魅力だと多くの人が感じている中にはフレームワークそのものも含まれているように感じますので、これからは両者を併せてお話を進めます。

 Cocoaフレームワークと言われるものは、AppKitフレームワークとFoundationフレームワークから成り立ちます。AppKitは主にGUIアプリケーションを作る際に使われる機能を提供し、Foundationはその下支えをします。
Foundationフレームワークはその名前通り基盤となる機能を提供しますので、AppKitが使われる場合には同時にFoundationも使われると考えてほぼ間違いないでしょう。
 それに対して、Foundationは単独で使われることも珍しくありません。一般のMacユーザーにはあまり馴染みがないかもしれませんが、UNIXであるMac OS Xには、ターミナルというアプリケーションから起動するいわゆる「UNIXコマンド」と呼ばれるアプリケーションが数多くあります。
 以下のページを見ると(Safariがフリーズする場合があるので開く時は注意!)、とても多くの項目が並んでいますが、この中でsection 1として分類されている項目(ざっと1,200ほどあります)は、それらはすべてターミナルから起動できるGUIを持たないコマンドです。

http://developer.apple.com/documentation/Darwin/Reference/ManPages/index.html

 これらの1,200余りのコマンドがすべてFoundationフレームワークを使って書かれているというわけではありません(おそらくは、ほとんどがCまたはそれに準ずるもの)。ですがFoundationを利用して、Objective-Cでこのような形態のアプリケーションを書くことができるのです。

 Foundationフレームワークの提供するのは、メモリ管理の機能やString、Array、Dictionaryなどの各種データ構造の基本となる型、Mac OSとやり取りする上で役に立つ様々なユーティリティなどです。
 この中でもメモリ管理はプログラムを書く上できわめて重要なことですからObjective-Cを学ぶ上でかなり優先度の高い事項です。
 ご存知の方も多いと思いますが、Objective-Cは2.0になってからガベージコレクターが使えるようになりました。ガベージコレクターというのは簡単に言えば、メモリの確保だけをプログラマーがやり、後始末に関してはシステムに任せておくことのできる仕組みです。
 プログラミングを学ぶ上で、メモリ管理というのは乗り越えるのが大変な壁のひとつであるため、ガベージコレクターの登場は一時は大きな話題になりました。ですが、iPhoneにおいては残念ながらガベージコレクターがサポートされていないことから、最近では余り話題に上ることもなくなりました。

 賛否両論あるものの、状況をわきまえて使えばガベージコレクターは便利に使える機能ではあるのでしょう。ただ、「ガベージコレクターがあるのだからメモリ管理については学ぶ必要がない」と言う人がいたら、それはちょっと考えが浅いのでは? と私は思います。たとえガベージコレクターが使えても、メモリという資源が有限であり、これをうまく使うことはやはり効率的なプログラミングをするためには欠かすことのできない技術だからです。

 さて、Objective-Cのメモリ管理というと、まずはalloc、そしてrelease、retainという言葉が登場してきます。そしてこれらと連携して使われるautorelease poolというものがCocoaのメモリ管理においては極めて特徴的なものです。
 次回はこの辺をさらに深く探って行きます。

◇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)2009 MOSA. All rights reserved.