C++プログラマから見たRuby

[ Ruby ]

わたしは仕事ではずっとC++を使ってきたので基本的にC++アタマです。その観点からRubyをみるといろいろ面白いですね。Rubyに比べると、Javaは随分C++に近い言語だなあとも感じます。

Abstractなメソッドを定義できない

ちょっとコードを書いてみてまず目につくのは、Rubyには仮想関数がないってことです。JavaやC#のインタフェースに相当するものもありません。

GoFのパターンでいうAbstractFactoryやらStateやらStrategyでは

  1. インタフェースを定義して、
  2. 同じインタフェースを備えているけど振る舞いが異なる複数の実装クラスを用意

します。C++はインタフェースはないけれども、全てのメソッドが純粋仮想であるようなクラスを書けばよいですな。でもRubyではどうすればいいんだ?

Rubyでは型チェックが行われない

型チェックが行われない、というとウソになりますね。実行前(コンパイル時、パース時)にはチェックされないというのが正しいでしょう。

しかしC++プログラマから見ると、感覚的には「Rubyは型チェックが行われない」ように見えます。ほとんどの場面では型よりも、そのオブジェクトがどんなメッセージに反応できるかってことのほうが重要です。

Duck Typing

全く型に関連がなくても同じメソッドを備えていれば、それは事実上同じ型として扱えると考えるのがDuckTypingです。「アヒルのように鳴き、アヒルのように歩くものはアヒルに違いない」といわけです。

StateパターンをRubyで実現しようと思ったら自然とDuckTypingになります。ConcreteState同士は型的には無関係だけど、そのStateに要求されるメソッドを用意しておけばよいわけです。

Rubyなひと(や、Smalltalkなひと)からすれば自然なんでしょうが、C++ばっかりだった私には新鮮な考え方でした。

C++では無理だよなあ...。と思っていたらやり方がありました。テンプレートを使うときはDuckTypingになってますね。

template <T>
class DoSomethingExecutor {
      public execute(T obj) {
            obj.doSomething();
      }
}

Tに要求されるのは、引数のないdoSomething()というメソッドが存在することだけで、型はなんでもOKですね。とはいえテンプレートを駆使して例えばConcreteStateの型がお互い関連のないStateパターンを実現するのは非常に困難ですね。

宣言不要

Rubyでは変数の型宣言が不要、メソッドの引数にも型が不要ですし、インスタンス変数ですら必要になったときに登場させればよいのです。インスタンス変数は@で始まるというルールは潔いです。コードコンベンションでインスタンス変数は小文字mではじめる、なんて決めるよりいいですよね。

attr_accessorは宣言ぽいですが、一行書くだけでC#でいうところのget/setを備えたプロパティが用意されると思うと楽するための宣言と思えます。普通はattr_accessorとかattr_readerを用意すれば十分で、排他とか値変換とかややこしいことがしたくなったらはじめて、C#でいうプロパティっぽいメソッドを用意すればいいわけです。

書いてみてどうよ?

楽です。速いです。モデルを考えるときには抽象クラス(あるいはインタフェース)があるほうが考えやすいですが、実装時に抽象クラスを書く作業は苦痛です。なんの仕事もしないけど型を定義するためだけに書くのですから。

宣言不要なのも楽な要素です。「この引数はどんな型にしよう?」とか悩む前にかけちゃいます。書いてから悩んでもいいわけです。

上にあげた以外でも、Rubyは短く簡潔に書けることが多いです。一番よく使うのがコレクションクラスのeachやらallやらmapにクロージャを渡す書き方です。


convertedArray = anArray.map { | x | MyConverter.convert(x) } 

なんてやると、anArrayの各要素をconvertした結果の配列がconvertedArrayに入ります。イテレータを作ってそれに対して云々、ってやり方がものすごくまどろっこしくなります。

デメリットは?

動的型チェックはC++プログラマには不安です。モジュール内部で使っているメソッドの引数を変更しよう、ってなときはコンパイラのエラーに頼って修正することもありますし。しかしUnitTestが正しく書かれていれば、型の問題はほとんどチェックできるようにも思います。UnitTestが失敗したときに、それが型の問題によるものだ、というのが即座に分からないことはありそうに思いますが。

チーム開発だと他に問題があるかもしれません。どのようなデメリットがあるのか(あるいはないのか)を実感するためには実際に経験をつまないとわからなさそうです。

トラックバック

このエントリーのトラックバックURL:
http://www.skoji.jp/mtbin/mt-tb.cgi/436

コメント

私は、使える言語と言ってよいのはC、PerlはV4の頃に覚え(つまり全くオブジェクト指向が導入されていない頃)たのがベースでそれより先は少しだけ(ハッシュが異様な進化を遂げてて驚きました)、Rubyはいいよと言われながら習得の機会を逃し、つまり、全くもって"使えない"人化している状況なので、まともなコメントはできません。
オブジェクト指向は理屈は一応分かっているつもりが、なんか実践がいまいち(余りコーディングの機会がないのも事実)。自分でJavaを組んでいて思うのは、「なんかクラス設計がすごく下手」。C++もいまだに覚えられないし。あああ。
すみません、単なるぼやきです。

momoさん> 私はその昔awk使いだったのですが(古いよ)、Perlは字面に馴染めず脱落。Perlはいまから覚えようとおもうと、ラクダ本があの厚さで二冊組みだからへなへなとなります。それに比べるとRubyのほうが(わたしには)随分とっつきやすかったです。

C++という言語は言語仕様がでかすぎて、まともに使えるようになるまでがかなり大変です。効率よく学ぶためにはEffective C++といった書籍は必須です。

と書いていて思ったのですが「C++に熟達してます」っていうのは今の時代もしかすると差別化要因になるのかも? 需要がないかもしれませんがね:D

クラス設計は悩みますよね。。わたしはオブジェクト指向がなんなのか、ようやく分かったと思えたのは5年ほど前です。で最近ようやく「そこそこ」の設計ができるようになってきた気がしています。

ああ、私も最初はawkでした。awkをちょろっと使いだした頃にPerlというのがあるんだよと教えられ…、そのうち、Rubyっていうのがいいらしいぞと聞いてなるほどとか言っているうちに習得し損ね。。。
# 年がばれますね。ええ、もちろんhttp://namazu.org/~satoru/misc/ggap.htmlではばっちり旧世代にハマりますのよ、おほほ。
Perlのラクダ本ははっきり言ってV4のものが断然読み易いです。それからすると、V5は訳が分からない状態になっているような。。。しかも上下で1万円はするし。。。(これ以上投資する気なし)Perlのオブジェクト指向は相当無理していると言われているし。
Javaも見よう見まねのレベルでしか組めないしなー。私は余り飲み込みの良い方ではないらしく、仕事上でそれなりの経験をつまないとプログラミング言語を習得できないタイプで、冗談ではなく真剣に悩み所です。(しかし、昨今そんな悠長な仕事は回ってきませんし。)
おまけに、UMLも読めないし、XMLにも暗いし。まずいよ>自分

追伸。Perlってやっぱり実はかなりヘンだと思います。なんというかね、あの、「何でもオッケー」なところが結局くせ者なんですよね、やっぱり。みんな言ってることですが。

momoさん>

わたしも基本的には旧世代です:)

怠け者なのでデフォルトでGNOMEがインストールされれば、twmでも十分なのにな、と思いつつそのまま使っちゃいますが。

言語は経験つまないと「本当には」習得できませんよね...。でも習得できるまでなんていってられないですよね。私は最近C#を使い始めてますが、とにかく本を買い集めつつ「本来はどう使うべきなのか」というのを言語仕様やらライブラリから読み取ろうと努力しています(この目的だとぐぐるのはあんまり役にたたんのですよね)。

Javaは結城さんの本がいいらしいですよ。とまた結城さんの宣伝をしてみたり。わたしは『プログラミング言語Java』で勉強してますが猛烈に読みづらい。

XMLはどうでもいいんじゃないですか:D 必要になってからということで。

Perlの世界では「やりかたはひとつじゃない」ってのが標語になってますよね。CPANとか超充実してるので実用性はきっとすごく高いんでしょうけど。

PerlのCPANの充実度はすごいものがありますね。去年の春から夏にかけて、仕事でPerlで開発する機会があり、やっと重い腰をあげて少しまじめにV5以降に取り組みだし、驚きました。あららーという感じ。
私は、GNOMEなんて入れたことないですよ(^^;、数年前に配転してきた今の部署はWindows一色のところでして、Cygwin+Meadowがないと仕事できないなどと言ってるのは、私だけです。ええ。。。かくしてUnix系のスキル・知識はその時点から一切進展なし。。。Javaも今のところじゃ組む機会ないし。せめてC++。。。
XMLはセマンティックウェブとか面白そう、と思うなら必携の気がするんですが、、、どうでしょう?

momoさん> うちもWindows一色でございます。嗚呼。

XMLは確かに基礎知識は教養として知っておいたほうがいいかもしれませんね。XSLTとかXPathとかの関係をおおざっぱに把握する程度には。

細かいことは必要になったら憶える! ということでいいかなあとは思いますが、でも興味をもった事には要不要にかかわらず突撃するべきとも思います。

亀レス(死語だよ)で、すみません。
結城さんは暗号本が初めてだったのですが、とても良かったので、Javaの本を買おうと思っています。しかし、積読解消していないのに、こじまさんのおかげもあって色々読みたいものが増えますねえ。(^^;)

細かいことは必要になったら、ですね。
で、何が使えるか使えないか程度の判断基準になる程度の知識、スキルは要る、と。私は今興味のある色々なことに対して、そのレベルが、そもそもちょっと怪しい。(割と細部が分からないと理解できないタイプなのかも。。。という気はします)

momoさん>
亀レスって久し振りにきいたような、でもまだ使われているような:D

結城さんのJava本はやっぱりいいみたいですが、でも上巻は強烈に初心者向けらしいですよ。わたしも読んでませんが。

>こじまさんのおかげもあって色々読みたいものが増えますねえ。(^^;)

これちょっと嬉しいです:D

>割と細部が分からないと理解できないタイプなのかも

それ分かります。というか私もそのタイプな気がします。神は細部に宿りますよね。

わたしはたいていのソフトウェア技術は本気で実装してみて初めて理解するので、仮に管理者になったとしても「仕事として実装する」という作業を仕事としてどこかに入れないと、多分技術屋としても、管理者としても使い物にならないひとになってしまうだろうなとおもっています。文章長いですが。

今の会社だときっと難しいんですが、目指すのは生涯いちプログラマです。


コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)