MOSA Multi-OS Software Artists

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

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

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

2009-03-03

目次

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

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

DSL(Domain-Specific Language=ドメイン固有言語)というのは、ある特定の分野(domain)について記述しやすいように設計された言語のことです。Rubyそのものは汎用のプログラミング言語ですが、その上にシームレスにDSLを積み上げ・構築しやすいのがRubyの良いところでもあります(後述する参考リンク先も参照のこと)。

今回は、Ruby+RubyCocoaを使って「CoreGraphicsによるPDFの描画」を記述するための簡易言語を作ってみることにします。

Leopard の/Developer/Examples/Ruby/RubyCocoa/Scriptsに、circle.rb というサンプルプログラムが入っています。これは、CoreGraphics を使ってPDFファイルを描画生成するものです。

-------------------------- circle.rb --
require 'osx/cocoa'
include OSX

path = "circle.pdf"
url = CFURLCreateFromFileSystemRepresentation(nil, path, nil)
rect = CGRect.new(CGPoint.new(0, 0), CGSize.new(612, 792)) # Landscape
pdf = CGPDFContextCreateWithURL(url, rect, nil)

CGPDFContextBeginPage(pdf, nil)
CGContextSetRGBFillColor(pdf, 1.0, 0.0, 0.0, 1.0)
CGContextAddArc(pdf, 300, 300, 100, 0, 2 * Math::PI, 1)
CGContextFillPath(pdf)
CGPDFContextEndPage(pdf)
CGContextFlush(pdf)
----


描画コンテキスト(上記プログラムでは変数pdfに格納)を生成して、そのコンテキストに対して「何かを描画」する、というのがCoreGraphicsによる描画の基本的な流れです。上記のようにPDF描画の場合には、ページの始めと終わりを明示して、その中に「何かを描画」します。この「何かを描画」する以外の部分は、おおよそ定型的な処理になりがちですから、そういうところを隠蔽して「何を描画するか」という点にプログラミングの焦点を絞るためのシンプルなPDF描画言語を作ってみましょう。上の circle.rb を以下のように記述できるようにすることを目標とします。

require 'pdf_drawer'

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


このDSLでは、CoreGraphicsのコンテキストに対する描画の関数群をコンテキストに対するメソッドの呼出として扱います。元々の関数名の先頭にはレシーバの型を意味する”CGContext”がついていますが、メソッド化するのであれば、これは必要ないので、メソッド名からは取り除きます(例えば、CGContextAddArcに対応するメソッド名を addArc にする)。また、BeginPageとEndPageに挟まれる描画手続き列はブロックで扱うことにします。

■ 下準備 — CoreGraphics関数名を抽出する正規表現パターンを考える

CoreGraphicsの描画関数はたくさんあります。それらひとつひとつを人力でメソッド定義するのは大変ですから、必要な関数名を抽出して、define_methodを使って動的にメソッド定義することにします。まず、このあたりの見当をつけるための下準備として、irb コマンドを使って CoreGraphics の関数名の見つけ方やプログラムによる名前の加工の仕方を調べてみましょう。

RubyCocoaをロードすると、CoreGraphicsの関数は全てOSXモジュールのメソッドとして組み込まれます。Rubyには、あるオブジェクトが応答できるすべてのメソッド名の配列を返す Object#methods というメソッドがあります。Object#methodsの結果に対して、正規表現によるパターンマッチを使ってCoreGraphicsの関数名を絞り込んでいきます。

 $ irb --simple-prompt
 >> require 'osx/cocoa'
 => true
 >> ary = OSX.methods.grep(/ ACG/)
 => ["CGGetEventTapList", "CGEventSourceButtonState",... 以下略 ]
 >> ary.size
 => 606


Enumerable#grep は、パターンにマッチしたEnumerableの要素を配列で返すメソッドです(ブロック付きの場合は配列化するかわりにブロックが呼ばれます)。

/ ACG/ は、Rubyの正規表現オブジェクトのリテラル表記です。” A”は「文字列の先頭」をあらわしますから、これは「”CGで始まる文字列」にマッチするパターンです。つまり、OSX.methods.grep(/ ACG/) は、「名前の先頭が “CG” で始まるメソッド名」の配列を意味します。どうやら Ruby から呼び出せるCoreGraphicsの関数は606個あるようです。

では、次にCoreGraphicsの描画コンテキストに対するメソッド的な関数名を抽出してみることにしましょう。これから作る DSL では、PDFコンテキストをレシーバとする関数をメソッド化の対象とするので、関数名が “CGContext” または “CGPDFContext” で始まるものだけを抽出します。

 

>> funcs = OSX.methods.grep(/ ACG(PDF)?Context/)
 => ["CGContextSetRGBFillColor", ... 以下略 ]
 >> funcs.size
 => 123


ここで、正規表現の中の “(PDF)?” の部分は、”PDF” または “” にマッチします。このパターンにより、CGPDFContext と CGContext 用の関数を抽出します。

DSL では “CGContextSetRGBFillColor” という関数名からレシーバの型を意味する”CGContext” の部分を取り除き、さらに先頭の文字を小文字に置き換えた、”setRGBFillColor” というような名前のメソッドを定義することになりますが、この名前の変換にも正規表現を使います。ということで次回に続きます。

■ DSL参考リンク

以下はDSLについて参考となるURLです:

ドメイン特化言語
http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DomainSpecificLanguage

DomainSpecificLanghage — 上記URLの原文
http://martinfowler.com/bliki/DomainSpecificLanguage.html

ドメイン固有言語
http://ja.wikipedia.org/wiki/ドメイン固有言語

「言語内DSL」の概念とRake
http://www.itmedia.co.jp/enterprise/articles/0703/20/news015.html

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

 てなわけで,1986年の労働者派遣法施行時には,自他ともに……というか,派遣するヒトされるヒト,その派遣をお願いするヒトという三者が等しく「高度で専門的な知識や経験を必要とする職種」と思っており,間違っても「後でその解釈を拡張して派遣できる業種を増やそうというトロイの木馬」としてこれに入れられたものではなかった,ということについてはガッテンしていただけただろうか。

 また実際にもコト「ソフトウエア開発」という職種に限れば,その後「そいつぁちょっとコンプライアンスというか,モラルの観点からどんなもんですかねシャチョー」というような職種の拡大解釈は行われなかったと思う。まぁこれは飽くまでワタシの管見の及ぶ範囲のことだけれどもね。

 問題は,それまでいわゆる「業務請負」という体裁で行われていたソフトウエア技術者の派遣という行為が,この法律の施行によってどう変化したか,である。え,オレも派遣だったが別に変わらなかったって? そりゃ仕事はプログラム組んでデバッグしてデバッグしてデバッグしてデバッグして(中略)デバッグするだけだもの,変わりませんがな。そうではなくて「事業としての派遣業務」の変化のことを言ってるのである。

 なんちうかね,実質的には人材の派遣であっても名目上「業務請負」というカタチであったころは,派遣する人材に関して請負側にまだ「裁量の余地」というものがあった。

 つまり(こういう表現がとっても大雑把なものであることは分かってもらえると思うが)「プログラマを4人,1年間欲しい」という依頼に対し,「人並み以上のプログラマ1人と並のを2人,ずぶの素人(新人)を1人派遣して,その業務をこなしながら新人を育てる」というようなコトが可能だったわけ。

 実際に1984〜5年,オレが「派遣」されていた会社では,Aという会社から5人,Bという会社から5人,Cから2人(このウチの1人がオレだったわけだが)という感じで人が集められており,2人しかいないウチは別として他の会社からのヒトの中には「今年入りましたプログラミングは初めてですけど頑張ります」が1人ずつ混じっていた。

 しかもその5人が全員同じプロジェクトにいるわけぢゃなく,新人のヒトリはオレたちのグループに入ってオレのような他の会社のニンゲンに「教育」されていたんだよね。もちろんオレの方ももっとヴェテランの人たちにいろいろと教えてもらった。派遣先,すなわちクライアント側もそういうのを当然あるべきスガタと認識していた,と思う。

 細かいことを言えば「A社が請け負った仕事はあっちなのになんでそこの新人がC社の請け負ってるこっちの仕事に従事してんだ」ということも言えるわけだけど,誰もそんな文句はつけない。そういう意味では……言葉にしてそんなことを確認し合ったことはないけれども,みんな「どこの会社の社員」というより「プログラマ仲間」としてスキルを高めあい,新人を育てていたんぢゃないかな。

 いいかげんと言えばいいかげんだし,営業のニンゲンに言わせれば同じところに「業務請負」に入ってる3社は「ライバル同士」かも知れなかったが(実際そういうコトを言われたこともある),プログラマ仲間にそんなことを気にするヤツはいなかった。チームを組んで一つのプロダクトを作り上げようというのだ,所属してる会社にこだわるよか,プログラマとしての実力の方が大事に決まってた。

 ところが,派遣法の成立・施行によってそういう状況は一変した。
(以下次回 2009_02_26)

                      

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

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

 皆さんこんにちは、高橋真人です。
 さて、前回の連載の載った号の藤本裕之さんの記事に「『高級言語』との訳語は適当でない、と中村正三郎氏に叱られたので…」とありました。私はその中村さんの「電脳騒乱節」(*注)のころからのファンで、彼の言語感覚や技術面でのアドバイスには一目を置いていますから、素直にならうことにします(笑)。
 ちなみに、先日中村さんのブログをチェックしていたら、そのうち紹介しようと思っていた言葉の出ているウォズの本(後掲)について触れられていました。(http://iiyu.asablo.jp/blog/2009/02/28/4144547 余計なお世話ですが、中村さんの語り口は過激で、時に下ネタも遠慮なく織り交ぜられています。ご覧になる場合にはご留意ください(笑)。)

 ついでですので、ここでそれを紹介します。私がこの本で取り上げたかったのは、まだ本の初めの部分である第2章の終わりのところなんですが、以下のようなくだりがあります。

「アップルをはじめ、いろんなところでいろんな人と仕事をしたけど、途中のやるべきことをすっとばして最終段階だけをなんとかしようとする人をたくさん見た。そんなの、うまくいくはずがないんだ。絶対に無理なんだよ。」※スティーブ・ウォズニアック著、井口耕二訳「アップルを創った怪物」2008年11月 ダイヤモンド社刊 ISBN978-4-478-00479-1

 この言葉に出会った時は嬉しかったですね。私も「硬派のためのプログラミング道場」なる講座をやってきて、基本から確実に積み上げていくことの大切さを強調してきた人間ですが、実際に仕事をしていますと基本を軽く考える「ノウハウのみを求める自称技術者」に出会うことも少なくないのです。われわれMacプログラマの多くが尊敬してやまないウォズの口からこのような言葉が語られたということに、私はとても安心を覚えます。

 さて、前置きが長くなりましたが、続きです。
 前回、「高水準言語は意味的な内容を記述する」と言いましたが、この「意味的」ということがピンと来なかった方もいらしたことでしょう。何を隠そうこの私も、HyperTalk程度は何とか使えていた今から20年弱前に、Cというプログラミング言語の存在を知って「こんなの人間のやれるものじゃない」と感じたことがあったのです。
 ですから、CやPerlの例を見て「意味的」と感じられるにはある程度の慣れが必要だというのも分かります。そこでその代わりと言ってはナンですが、逆に低水準言語というものがどういうものかをお見せすることで、逆に高水準言語の「分かりやすさ」を感じてもらいたいと思います。
 前回、Cで書いたサンプルをお見せしましたが、これをコンパイラが“コンピューターに分かる”ように翻訳したものをお見せします。もっとも既にお話しした通りCPUは数値しか理解しません。ですが、マシン語の数字の羅列を見せられても、人間には、それはただの数字の並びにしか見えませんから(笑)、マシン語に置き換えられる前のアセンブリコードをお見せします。
 以下は、Xcode3.1上でGCCというコンパイラを使って生成したアセンブリコードですが、せっかくですのでIntel用とPowerPC用をお見せします。ただ、GCCの吐き出したものはそのままだといずれも400行以上あり、多くは内部的な情報を表しているだけですから、元のCのプログラムの動作に関係しない部分はざっくりと省略します。さらに、ラベル(コードの位置を示す印)等も取り除いてありますので、このまま動かすことのできるものでないことはあらかじめお断りしておきます。

《Intel CPU版》

_main:
   pushl   %ebp
   movl    %esp, %ebp
   pushl   %ebx
   movl    $10, %ebx
   subl    $20, %esp
   movl    %ebx, 4(%esp)
   movl    $LC0, (%esp)
   call    L_printf$stub
   decl    %ebx
   jne L2

   addl    $20, %esp
   xorl    %eax, %eax
   popl    %ebx
   leave
   ret


《PowerPC版》

_main:
   mflr r0
   stmw r30,-8(r1)
   lis r30,ha16(LC0)
   li r31,10
   la r30,lo16(LC0)(r30)
   stw r0,8(r1)
   stwu r1,-80(r1)
   mr r4,r31
   mr r3,r30
   bl L_printf$LDBL128$stub

   addic. r31,r31,-1
   bne cr0,L2

   addi r1,r1,80
   li r3,0
   lwz r0,8(r1)
   lmw r30,-8(r1)
   mtlr r0
   blr


 いかがでしょう?
 所々、意味ありげな文字列らしきものも見て取れますが、前回お見せしたCのコードと比べても、というか、比べようがないほどに意味不明なものに見えるのではないでしょうか。
 さらに特徴的なのは、Intel CPU向けとPower PC向けのものに全く同じ部分が存在しないことです。この二つが「同じように動作する」と言われても、なかなか納得できるものではありませんよね。

 このように、実際の低水準言語のコードを見てしまうと、Cのコードはずっと人間に分かりやすく感じられませんか? 何より、Cで書いたコードはコンパイラが対象とするマシンに合わせて変換を行ってくれますから、コードを書く時に「今書いているコードはどちらのマシン向け?」などと意識する必要はほとんどありません。
 このように対象マシンごとに書き方を変える必要のないのが高水準言語の特徴でもあり、これをポータビリティまたは移植性などと言ったりします。

注記:「電脳騒乱節」
技術評論社から出ていたパソコン月刊誌「ざべ」(最初はThe BASICという名だったが通称がそのうち正式名称になった)に掲載されていた中村正三郎氏の連載記事。過激な語り口と内容でいろいろと物議を醸したこともある。

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