いったい Ruby のどこがいいのか? どのくらいいいのか? つーか本当にいいのか? まずはそのへんから。
言語の好き嫌いは人によってさまざまだ。最初に覚えた言語が一番い
いっていう保守的…いや、わるかった、信念の強いひともいる。ある
いは、スピードが速いのがいいっていうひともいるし、'write only'
にできるのがいいっていうひともいる。さらには「新しいからいい」
という節操のない…じゃなくて、好奇心の強いひともいる。
が、しかし、しかしだ。Ruby がすごい理由はどれもあてはまらない。 Ruby が Ruby たる所以は「書くのが楽しい」ところなのである。 これはめちゃくちゃ重要なことだからもう一度書こう。
Ruby は書くのが楽しいプログラム言語なのだ!
なにが楽しいってそりゃいろいろあるけれども、まずインタプリタだから、 サクっと書いてサクっと動かせる (そしてバグがみつかる)。
それから、組み込みのクラスライブラリがやたらに高機能。String
、
Integer
、Array
、Hash
、Regexp
あたりがあればたいていのものはで
きてしまう。逆に、ときたま C なんか使ったりすると「うわああっ、
Regexp
が欲しいよーーー」と叫んでしまうことも度々である。しか
も高機能とはいってもおしつけがましくないのがポイント。「どーで
もいいところ」だけがうまく覆いかくされていて、その他の重要なと
ころ、例えばアルゴリズムであるとか、「ここで何をしたいのか」と
いうことがストレートにだせる。
そして、文法に制限が少ない。たとえばこんなことも余裕でできる。
arg = if a == 'a' then 'a' elsif b == 2 then 'b' else 'c' end
いちおう文末にはセミコロンが置けるけどあれは C / Perl ユーザの
ためのリハビリ用でしかないし、Perl 由来で修飾の if unless
もあ
るし、メソッド呼びだしの括弧も省略できるし、行の最後がカンマや
二項演算子なら次の行に続くんだな、と勝手に判断してくれる。これ
は次の例を見れば一目瞭然だろう。
obj.method_call arg1, arg2, arg3 if condition str = 'a' + 'b' + 'c'
また「リテラルがそのままオブジェクト」というのもいい。
例えば、スクリプト中で 'a'
と書くともうそれがすでに String
オブジェクトであり、そのオブジェクトに対してメソッドを呼ぶ
ことができる。
# str に 'string' を大文字にしたものを代入 str = 'string'.upcase
3 と書いたらそれは Integer
オブジェクト
(正確には Fixnum
オブジェクト)である。
# 三回くりかえせ! 3.times do print 'ok' end
こういう書きかたは始めはちょっとびびるけど、このような表現も Ruby の気持ちよさを加速している重要な要素だ。このへんは説明を 読んでいるだけではわかりづらく書いてみるとよくわかるという類の ものなので、ぜひ一度実際に自分で試してみてほしい。
Ruby のソースコードは美し(く書けることがあるらし)い。先に述べ た「やりたいことがストレートに出せる」ということとも関係あるの だが、とにかく余計なものがない。
また、動作に関してもそうだ。そのいい例がイテレータ。配列にアク
セスするのに C みたいにいちいちサイズチェックをしながらやる必
要がなく、each
一発ですむ。
['a','b','string'].each do |i| print i end
これを実行すると、'a' 'b' 'string'
を順番に i
に代入して
do...end
が実行される。つまり、ループの while
文とかループカウ
ンタとかが each
メソッドの中に隠蔽されているわけだ。そのおかげ
でユーザはいちいちアクセスの仕方を知る必要がない。
ちなみに上の例は %w
を使うともっときれいに書ける。
%w( a b string ).each do |i| print i end
%w
は文字列配列リテラルを記述するための専用記法だ。
ところで Perl にも each
はあるけれど、組みこみ演算子で、ユーザー
が再定義することなぞ当然できない。しかし Ruby では自分で好きな
イテレータを定義することができるのである。
# ユーザレベル each def each( array ) i = 0 while i < array.size do yield array[i] i += 1 end end # 自分の each を使ってみる each [ 1, 2, 3 ] do |i| print i end
yield
のところで、制御がブロックの中に返ってくる。「yield
はブ
ロックの呼びだし」と考えるとわかりやすいと思う。高階の関数みた
いなもんだな。
それから、モデルの面から言っても Ruby は美しい。値は整数も含め て全てオブジェクトだし、クラスもオブジェクト、コードもオブジェ クトにでき、そしてオブジェクトでないデータは存在しない。
Lisp ではプログラム自体がリストなので、実行時にプログラムを変
化させることができる。Ruby では「プログラムもオブジェクト」と
いうわけではないのだが、そのように扱うことはできる。例えば前節
でちょっと出てきた「ブロック」をオブジェクト化した Proc
もこの
用途に使えるし、eval
や module_eval
というメソッドを使うことで
文字列をコード化することができる。こういうものを組み合わせると
実行時にクラスにメソッドを加えたり、クラスを作ったりできる。
class A def define_a type.module_eval %{ def a print 'a is called' end } end end
この define_a
を呼ぶと、メソッド a
が定義される。この例そのま
まではなにもおもしろくないけれど、実行時に文字列をいろいろいじっ
てから module_eval
してやればもっといろいろなことができる。
ついでに豆知識を一つ。今、実行時にクラスを作ることを特別なこと
のように言ったけれども、実はすべてのクラスは実行時に作られてい
る。つまり、class
文は、「クラス定義」というよりも、「クラス登
録文」と言ったほうが近い。
Ruby はインタプリタ言語だから、速度の心配をする人がいるかもし れない。もちろん、例えば C で書いたプログラムと比べれば Ruby スクリプトは遅いにきまってる。だが……それがなんだというのだ!
例えば C のプログラムより 50 倍遅くなったとして、実行時間はど
のくらい変わるだろうか? もし C のプログラムが 0.01
秒で終わる
としたら、Ruby 版は 0.5
秒。あなたのプログラムは 0.49
秒速くす
るために C で書く価値があるのか?
しかも、(インタプリタ全般に言えるけど) 大量の文字列処理や入出 力がからむと、差は小さくなる。Ruby で書くのはそういうものが多 いから、さらにネイティブ言語にこだわる必要は小さい。
プログラムは開発の時間よりも保守の時間のほうがかかるというのは もはや常識だけども、Ruby で書いてあれば例えば、C で書いたプロ グラムよりも楽に保守できるはずだ。そういう点でも Ruby は非常に いい。
だいたい、スピードに対してごちゃごちゃ言うなら C じゃなくアセ ンブラで書けばいい。それをなんで C で書いてるのかって言えば、 それはもちろん「コードがわかりやすい」とか、「早く書ける」って のが理由だろう。そして、Ruby は C よりわかりやすいし速く書ける。 ということは、「C よりも Ruby」というのは非常に自然な選択では ないだろうか?
CPU はじめハードはどんどん速くなってくれる。いまはそれを某 OS とかが食いつぶしてくれたり、某ワープロソフトがどーでもいい機能 のために使ってくれたりするのだけど、それはあまりに悲しい。もっ と、「カワイイ」とか、「カッコイイ」のために使うべきではないだ ろうか。システム部分はサクッと Ruby で書いてしまえば、我々人間 はそういうコトに集中できる。
それにほら、そうすればしばらくイン×ルも CPU の性能を上げ続け る理由ができるでしょ? (^-^)
本家の比較ページはリンクがなくなってしまいましたがこっちは まだまだいきますよ。
え? C はいいと思うよ。うん。おれは好きだな。ポインタ演算をしく じるとすぐに逝ってしまう儚さが……イイ! (・<>・)
なんて、ちょっと 2ch
風味にしてみた。でも慣れないことするから
顔文字がうまく書けない。
とりあえず Perl5 のオブジェクト指向は使いたくないじゃない。 Perl 好きな人も Perl4 レベルがいいって言うし。だから オブジェクト指向嫌いなら Perl。好きなら Ruby。ということで どうよ?
あ、でも一言書いとくと、Perl と Ruby は似てない。みんな似てる っていうけどそんなのは大嘘だ。Perl と Ruby が似てると言える なら、Ruby は C と Lisp と Smalltalk にも同じくらい似てる。
Ruby と Python は確かに似てる。特にちょっと見た感じでは。が、 ちょっと使っていくとかなり違うことがわかる。
全般的に Python が禁欲僧みたいな印象なのに対し Ruby
のほうはずっとノリノリな感じである。その違いは、まあ
文法にも結構出ているのであるが、むしろクラスライブラリを見ると
よくわかる。Ruby のほうの特徴はひとえに「大クラス主義」につき
る。これはまつもとさんが ruby-list
で言っていたことだが、Ruby
のクラスはかなりたくさんの機能をかかえこむ傾向にある。その対極
は Java
。機能ごとにひたすら分割して直交性を上げまくる。Python
は Java
よりはクラスが大きいが Ruby よりはずっと小さい。
んで結論を言うと、両方やって趣味の合うほう使え。
ちなみにおれが四年前に Ruby を選ぶ決め手になった理由は
「Ruby のほうが名前がカッコいい」であった。人生なにが
きっかけになるかわからないね。そうそう、Linux と FreeBSD
で
迷ったときも名前で決めたよー。
えー……。静的だし……。ほんの最近までジェネリッククラス作れな かったし……。文法は C ひきずってるし……。特に速いわけでもす ごく便利なわけでもないしさあ。なんかあれだなあ、もうちょいエキ セントリックなのがいいなあ。
まあそれはいいとして、Ruby と Java
両方やってみるというのは悪
くない。Python のとこで書いたように Ruby と Java
はある意味対
極にあるので、両方やると世界が広がる。特に静的言語ばっかりやっ
てきた人は Ruby で動的なオブジェクト指向を体験しておくといい。
そうすると Java
の interface
なんかがわかりやすくなる。
Scheme いいよねー! Common Lisp は折衷くさくて嫌いさ。call/cc
とか、名前がもうカッコよすぎ。
え、比較になってない? そりゃすまんかった。だってさー、なにを 比較したらいいのかわかんないんだもん。
あんまちゃんと勉強したことないんだけどね、よくキレイって聞くね。 でも Lisp もそうだけど、なんといっても文法がシンプルすぎるのが 弱点な気がするな。プログラム言語ってのは論理だけじゃなく人間の 意思を反映しなきゃいけないものだから、やっぱそれなりに泥くさい ところが必要だと思うんだよね。日本語の構造が Smalltalk みたい だったらイヤじゃん。それと同じ。
少なくとも言語仕様に関しては Ruby はとっても Eiffel
に似てると
思ったりする今日このごろ。たしかに組み込みで表明の構文があった
りするわけではないけれども、根底に流れる思想がすごく近いような
気がするな。まつもとさんは『オブジェクト指向入門』にかなり影響
を受けたようなのでそれも当然と言えば当然なのだが、みんなあまり
指摘しないのであえて指摘してみた。
MS
ももう見捨てたみたいですし……。
正式バージョン出たんだっけ? とりあえずモノがないとさあ。
それはそうと、D
なんて名前にならなくてよかったね。
……まぞ?
おれも持ってるよ、Delphi ver3
と Kylix
。がんばれボーランド!
MS
なんかに負けるな!
Object Pascal
はねえ、嫌いじゃないんだが、Ruby やってしまうと
処理がもう面倒で面倒で……。特に GC がないのが辛い。そんなわけで、
Apollo
を使ってメイン処理は Ruby に丸投げ、GUI は Delphi
で
サックリやる。というのがなかなかいい感じじゃないかと思う。
他にも Ruby を COM オブジェクトにして Delphi
から使うってのも
できるんだよね?
Copyright (c) 1998-2002 Minero Aoki
<aamine@loveruby.net>
This site is link free.