2009-02-03
目次
りんご味Ruby 第40回 藤本 尚邦
前回までに実装してきた、真偽値アクセッサ宣言のための疑似的な構文糖衣attr_predicateは、アクセッサ名を列挙するだけというとてもシンプルなものでした。しかし私としては、ブロック付きの構文糖衣にこそ、Rubyに新しいDSL(Domain-Specific Language)を導入するときの醍醐味があると思います。ということで、今回はブロック付きの構文糖衣を取り上げます。
■ ブロック付きの構文糖衣の例
ブロック付きの構文糖衣が導入されるのはどんな場合でしょうか? 2つほど実例を上げていきます。
◇ rakeコマンド
Leopard には、Rubyで実装されたrakeというコマンドが入っています。以下はrakeコマンドのマニュアル(ターミナルで man rake を実行して見ることができます)からの抜粋です:
Rake is a simple ruby(1) build program with capabilities similar to the regular make(1) command.
ここにあるように、rakeは、makeコマンドのような機能を実装したコマンドです。何かの手順を実行するタスクや各タスク間の依存関係を、Rakefileと呼ばれるタスク記述ファイルにあらかじめ記述しておくと、rakeコマンドを呼び出すことによって、各タスクを適切な順序で実行させることができるというものです。
rakeの最大の特徴(makeとの違い)は、タスク記述ファイル(Rakefile)の構文にあります。以下はRakefileのごく簡単な一例です:
--------------------------------------- Rakefile ---
task :default => :now
desc "時間を読み上げる"
task :now do
t = Time.now.strftime('%H:%M')
puts t
sh "say #{t}"
end
----
いかがでしょうか? タスクの説明や内容が読みやすく表現されていると思いませんか? 実はこれはRubyのプログラムそのものです。ここの task や desc は、rake によってRubyに導入された構文糖衣(あるいはDSL)なのです。この種の記述ファイルの表現にはXMLが用いられることが多い昨今ですが、人が読み書きするという観点から考えると、DSLを導入したRubyプログラムで表
現するという方法もなかなか良いと思いませんか?
上のRakefileをどこか適当な所(以下の例では /tmp)に保存して、ターミナルでそのディレクトリに移動すると、以下のようにrakeコマンドを実行することができます:
$ cd /tmp
$ rake -T # タスクの一覧を表示
(in /private/tmp)
rake now # 時間を読み上げる # 表示されたタスクの一覧
$ rake # デフォルトのタスクを実行
(in /private/tmp)
12:49 # 時間を読み上げる
◇ RubyCocoa の ib_action
もうひとつの実例として、RubyCocoa に含まれている構文糖衣 ib_action が導入されたときの流れを見ていくことにします。
Cocoaのアクションは、単なるObjective-Cのメソッドにすぎませんから、RubyCocoa ではもともと単なるメソッドとして定義すればよいものでした:
def buttonPressed(sender)
# ボタンが押されたときの処理
end
その後Leopardになって、Interface Builder と Xcode のバージョン3からは、ソースコードをパースして発見したアクションをnibファイルに自動的に反映するという機能が加わりました。しかし、上のようにアクションを単なるメソッドとして定義しただけでは、InterfaceBuilderは、どのメソッドがアクションなのか知る術がありません。そこで、ソースコード中にアクションの宣言に相当する記述が必要だということになり、アクションを宣言するためだけの構文糖衣が導入されました:
def buttonPressed(sender) # アクションの定義
...
end
ib_action :buttonPressed # アクションの宣言
(注: アクションの宣言は、Interface Builderやその他の解析ツールなどに情報を与えるためだけに記述されていて、実行時には何もしません)
ここで、定義と宣言のために アクション名(buttonPressed) を2度重複して書くのは無駄だし、タイプミス(typo)によりバグの原因になることもあるかもしれません。そこで、構文糖衣ib_actionのブロック部にアクションメソッドの定義を書くことができるようにしました:
# アクションの宣言と定義
ib_action :buttonPressed do |sender|
...
end
■ ブロック付きメソッドの定義
Rubyにおいて、疑似的な構文糖衣のその実体はメソッドの呼出ですから、Rakefile の task によるタスクの記述や RubyCocoa の ib_action によるアクションの宣言・定義も、実際にはメソッドの呼出ということになります。したがって、ブロック付き構文糖衣を導入するということは、ブロック付きメソッドを定義するということになります。
これまで、ブロック付きメソッドの使い方(呼び出し方)については何度も書いてきましたが、ブロック付きメソッドの定義方法についてはまだ触れていません。ということで次回に続きます。
藤本裕之のプログラミング夜話 #153
承前。1986年に成立した「労働者派遣法」によって派遣が可能になった「高度で専門的な知識や経験を要する」13職種というのの内訳は以下のようなものだった。
ソフトウェア開発/事務用機器操作/通訳・翻訳・速記/秘書/ファイリング/調査/財務処理/取引文書作成/デモンストレーション/添乗/建設物清掃/建築設備運転・点検・整備/案内・受付・駐車場管理等。
どっすか? あなたの尺度でこれらの職種「高度で専門的な知識や経験を要する」と思いますか? オレの極く個人的な印象を言わせていただけば、この中でそう思われるのは「通訳・翻訳・速記」、「財務処理」、「取引文書作成」、「建築設備運転・点検・整備」くらいである。……いやもちろん「ソフトウェア開発」も入れたいが、派遣ではない正社員でありながら、どう贔屓目
に見ても「高度で専門的な知識や経験」をお持ちとは思われないヒトをたっくさん知っているし、以下の議論をより客観的なものにするため敢えて外した。
これらの職種の「専門性」というものを考えてみよう。
たとえば通訳である。これがかなり専門的な仕事であることは誰にでも分かる。もちろん個々人を見ればピンキリで、かつてWWDCでセッションの日本語同時通訳をやってたヒトの中には画面に現れるアイテムとしての「Window」を全部「ウインドウズ」と訳したすっとこオヤジもいたし(自分がどんなイベントに呼ばれたのかくらい認識しろよ、と思ったな)、「Harddisk」を「堅い円盤」と言ってわれわれの失笑を買ったお姉さんもいたが、それでもあのスピードで喋り言葉を日本語に置き換えて行けるというのは「高度で専門的」なコトだと思う。
あるいは速記。子供のころ欲しかった玩具に「スパイ大作戦手帳」(だっけ?)というのがあって、水に溶ける紙だの犬にしか聞こえない笛だの(あれはホンモノだったんだろうか? ニセモノでもこっちにはわかんないわけだが)そうした怪しいアイテムの中のひとつに速記記号の表(何式だか知らない)があって、20分ほど練習して挫折した憶えがある。あれ実はちゃんとした速記士という資格があるのだが、テープレコーダ……いまはICレコーダだな、が普及した今となっては法廷と議会くらいしかハタラキ口がない。でも確かに「高度で専門的」な感じがする。
財務処理……すぐ連想するのは簿記、会計士くらいか。取引文書作成ってのは行政書士? 公証人かしら? 建築設備運転・点検・整備ってのはつまりブルドーザーだのショベルカーだのクレーンだのを操作したりってことだよね。たまにどう考えてもまずいだろってな工事をやってクレーンぶったおしちゃうヒトもいるが、いや逆にいるようだからこそこれも「高度で専門的な知識や経験」を持ってるヒトでないと困る。
でもさ、デモンストレーションってなんすか? これ、どう考えても展示会のコンパニオンのことだろ。建設物清掃ってのはビル掃除のおばちゃんやないの? 案内・受付・駐車場管理等っていうのもそのタグイでしょ? ちうか、駐車場管理なんてオレだって学生時代にバイトでやったことがありますがな。事務用機器操作ってのも怪しい。1986年当時を思うとこれ、たぶんキーパンチャーとかオペレータを想定してるんだと思うけど違うかな?
そういうことを指摘したヒトがいたのかいなかったのか、1986年当時半分会社に寝泊まりするような感じで仕事をしていたオレにはさっぱり記憶がないのだが、いまになって見返せばこれ、つまりは「展示会のコンパニオン」とか「ビル掃除のおばちゃん」とか常雇いの正社員にするとコストが掛かりすぎる職種のニンゲンを派遣で済ませるために、実際には派遣会社なんかにマネージ
メントされなくても仕事が見つかる通訳とか会計士とかを混ぜ込んで「高度で専門的な知識や経験」という包装紙でくるんで見せたものだったんだとわかる。そうでしょ?
で、もちろん問題はわれわれが属する「ソフトウェア開発」である。この職種はこの法律に「展示会のコンパニオン」側として入れられたのか「通訳や会計士」として入れられたのか、というハナシだ。そんなのわかりきってるぢゃないかって? そりゃ今となれば前者であることは明白なように思われる。が、1986年という時期を考えると、施行時からそう考えられていたと断言できないフシがあるんだよね……。
(以下次回 2009_01_30)
高橋真人の「プログラミング指南」第151回
皆さんこんにちは、高橋真人です。
さて前回、Mac以外の環境でプロとしてやってきた経験のある人の中から、特にWeb系のそれもスクリプト言語オンリーでやってきた人を取り上げて、これらの人々がiPhoneのプログラミングに取り組むにはどのようなアプローチがよいのか、という疑問を提示しました。
今回はその延長線上で話を進めていこうと思いますが、同時に前回の冒頭に掲げた「今までプログラミングに触れたことがなかった人」に対しても参考になるような形でお話を続けていきたいと思います。
さて、「スクリプト言語がプログラミング言語とどう違うのか」と聞かれてもよく分からない人もおいででしょう。前回は“ネイティブ系のプログラミング言語”という言い方でスクリプト言語と対比させてみましたが、そもそもこれらはいったい何なのでしょうか?
プログラミングということを意識している人であれば、コンピューターがCPUという電子部品によって動いていることはご存知でしょう。CPUはCentral Processing Unitの略で、日本語では中央演算処理装置などと表現されたりします。要は、コンピューターが各種の処理を行うための中核部分ということになります。
また、コンピューターの中ではすべてのものが数値で表されます。「コンピューター」というとよく「デジタル」という言葉が付いて回りますが、そもそもデジタルとはdigitという数字を意味する言葉から派生した語ですので、数値がすべてであるコンピューターにとってデジタルという言葉が付いて回るのは当然です。
私が一般の方にコンピューターのことを説明していると「プログラミング言語でコンピューターって動くんでしょ?」とおっしゃる方は多くいます。もしかしたら、皆さんの中にもそう思っている方がおいでかもしれません。しかし、CPUが直接プログラミング言語を理解するのではないのです。CPUが理解できるのはあくまで数値だけなのです。
細かくて申し訳ないのですが、ここでちょっとお断りを(笑)。
CPUが理解するのは数字ではなく、数値です。以下にも「数値」と「数字」という言葉が頻繁に出てきますが、両者は意図的に使い分けられていますので、どうか違いを意識して読んでください。
さて、「CPUは数字ではなく数値を理解する」ということは、つまりCPUは123456…という数字を直接理解できるわけではなく、あくまで電気的に表現された数値を受け取って動くということです。
コンピューターの中では数値は2進数で表されます。0と1だけを使って数値を表すのが2進数です。分かりますか? 例を挙げます。私たちが日常使う10進数を2進数で表すと、55は110111となりますし、100は1100100となります。
なぜ2進数なのかといいますと、今のコンピューターではこの形で数値を扱うしか、高速で精度を保った処理をこなせないからです。コンピューターの中では2進数は具体的には電圧の高低によって表現されたりします。
余談ですが、「デジタルって何?」と問いかけると、「0と1でうんたらかんたら…」なんて答えられる方がいらっしゃいますが、これもこのCPUが2進法で数値を扱うというところからきているのだと思います。しかし、0と1に特別な意味があるわけではなく、コンピューターにとって数値は0と1でしか表せないというだけのことです。
ですからCPUがいくら0と1で数値を表すからといっても、人間までがそれに合わせる必要はありません。0と1だけが延々と羅列されているとケタを読み違えたりしやすいですから、通常プログラマーは16進数というのを使います。「なぜ、いちばん馴染みのある10進数じゃないの?」と疑問に思われるかもしれませんが、コンピューターの2進数とやり取りするには16進数の方が都合が
よいのです。
ごく簡単に説明しますと、2進数の4ケタ分が16進数の1ケタ分にピッタリと収まるのです。10進数だと端数が出てしまうために、どうしても収まりが悪いのです。具体例は省略します。ピンと来ない方はWebなどを検索してみてください。
さて、「コンピューターには数値しか分からない」となると、改めて「プログラミング言語って何?」という疑問が湧いてくるかと思います。そこで、一般にプログラミング言語と言われるもの(ここにはスクリプト言語も入ります)を低レベルから高レベルまで順に見ていきます。低レベルや高レベルと言っても、頭がいいとか悪いという意味で使っているのではありません。
プログラミングにおいては、低レベル言語(もしくは低級言語)や高レベル言語(高級言語)という言い方をしますが、これはCPUに近いものを低級、遠いものを高級と言っています。近いというのはつまり、人間がコンピューターに指示を与える際に、直接的に指示できるということです。逆に遠いという場合には、人間とコンピューターの間に仲介者(基本的にはソフトウエア)が何
段階かにわたって入ります。
すぐあとで説明しますが、低級言語ですと人間が直接数値を使って命令しなければなりませんが、高級言語になると、かなり人間的な感覚で命令を記述できるようになります。語弊があるかもしれませんが、高級言語ほど人に優しいということが言えるでしょう。
さて、CPUが直接理解できる数値による命令体系を「マシン語」または「機械語」と呼びます。低レベル言語の中でもこれはもっとも低い位置に属した言語です。「語」という文字が付いてはいますが、人間が見るとただの数字の羅列でしかありません。それをコンピューターに読み込ませる、つまり電気的な信号に変えて送り込むことによってCPUは動作します。
マシン語からちょっとだけレベルが上がったものをアセンブリ言語と言います。マシン語が数字だけの羅列であったのから比べると、アセンブリ言語は記号めいてはいるものの、人間が見ると何らかの指示をするための文字の並びであることが見て取れます。先ほどレベルが上がると仲介者が増えると言いましたが、アセンブリ言語はそのままではCPUが理解できないので、一種の変換器
を使ってCPUが理解できるマシン語に変換をします。この変換器のことをアセンブラと言います。
おおざっぱに言うと、アセンブリ言語は「マシン語を人間に分かりやすい表現に置き換えただけ」と言えますので、基本的には1対1の対応で変換をします。ですから、翻訳機というほどの凝った仕組みではありません。変換表を元に、単純に置き換えていくだけの作業でもありますから、量が多いのをいとわなければ人間が自分で(数値への)変換をすることも可能です。こういうのを
「ハンドアセンブル」と言います。
さて、このアセンブリ言語の仕組みを多少知的にしたものがマクロアセンブラです。アセンブリ言語がマシン語に「そのまま」置き換わるのに対して、マクロアセンブラは少し人間に優しくなっています。
例えば、特定のメモリ領域に名前を付けて変数という概念を表したり、特定のアドレス値にラベルを付けて、それをジャンプ(通常順に行われる処理が、特定の場所にジャンプする)する時の印にすることができたりします。
以上が、低レベル言語と呼ばれるものです。
次回は、もう少し上のレベルに上がっていきましょう。
◇MOSAからのお知らせと編集後記は割愛します◇