Entry

プログラミングメモ - Ruby には Ruby なりに大規模開発の作法があるのだと思う

2009年11月30日

『まつもとゆきひろ コードの世界』をつらつら読ませてもらっています。

まつもとゆきひろ コードの世界‾スーパー・プログラマになる14の思考法
まつもとゆきひろ
日経BP出版センター
売り上げランキング: 84500
おすすめ度の平均: 4.0
4 Rubyに導入された思考法

どうも,Ruby をはじめとした LL の,特長でもありボトルネックでもあると指摘されている点は,動的型付け言語と静的型付け言語の区別に収斂されている気がします。LL の類書の中でも,言語仕様の特徴について自覚的な著書は,必ずと言っていいほどこの点に対する言及がある。本書も,その通り。

その前に,なんだか,この頃ずいぶんと静的型付けと動的型付けに対してこだわっちゃってるので,注記しておくと,こゆことを話すのはあたしが Ruby を嫌い/好きとか,C++ サイコーとかいった,プログラミング言語の優劣の話をしたいからではありません。実際,あたしゃ普段 C++ のプログラムを書いているわけですけれど,ちょっとした用事には Ruby を使っていたりする。使い始めたのも Rails が流行り始めるずっと前の Ruby 1.3 くらいだし,OOP の基礎も Ruby で身に付けたといってもいいくらいです。Ruby をはじめとした LL には,恩には着ていても恨みを持っていることはありません。念のため。

で,本書の話。

Ruby では,実際に実行してみないと型の不整合が検出できません。Java のようにコンパイル時の型チェックが厳しい言語であれば,必ずチェックされるエラーが,Ruby では見逃される可能性があります。このため,規模が大きなプログラムでの信頼性が下がるという主張です。

しかし,考えてみれば,プログラムのバグは型の不整合を伴うものばかりではありません。むしろ,型の不整合は比較的簡単に見つかる間違いでしょう。Ruby の型チェックは実行時に行われますが,逆に言えば実行すればきちんと型をチェックするということです。大規模プログラムに必要な信頼性を維持するためには網羅的なテスト・プログラムが不可欠で,もし網羅的にテストされているのであれば,言われているほどコンパイル時の型チェックによるメリットは重要ではないかもしれません。

『まつもとゆきひろ コードの世界‾スーパー・プログラマになる14の思考法』(まつもとゆきひろ,日経BP出版センター,2009年,p174)

この話は微妙だな……と。

大規模開発というのがどこまでの規模を示しているのか,なかなか把握しづらいところがあるんですけれど,例えば業務システムでいうと,基幹のすべてと言えば,間違いなく大規模なシステムだと言っていいのだと思います。メーカー系の業務システムで言うなら,受発注管理や資材在庫/現品管理,生産管理からワークフロー/図面管理,人事労務管理や会計システムといったところが挙げられます。これらをすべて(信頼性を伴ったまま)Ruby で書けるだろうか,という話に置き換えられそうです。

ま,業務システムでやってることは,どちみち大した話じゃないので(システムリソースをフルに使って高効率なアルゴリズムやデータ構造を研究しないと動かないようなシステムではないという意味),書いて書けないことはないんだと思います。問題は「信頼性」を担保したシステムを効率よく書けるかということなんだと思う。

そうした点で見ると,あたしは「少なくとも現在の業務システム開発を踏まえる限り」ちと Ruby では厳しいと思っています。

まず,引用についてなんですけれど,網羅的にテストをするのは,規模の大小にかかわらず必ずしなくちゃいけないことなので,それはそうなんだと思います。網羅的なテストをすれば,型の不整合を検出できる可能性がある。ただ,Ruby の場合は,動かさないと検出できないし,動かした後も「型」の概念がそもそも緩いので,型の整合性を正確に検出するにはメタ関数を使う必要があります。これは,先日話したとおり(継承関係のないオブジェクトも通してしまうとか)。

つまり,「網羅的なテスト」といっても,ユニットテストの内容に「型の整合性テスト」という項目が増えるわけで,テストの分量としては静的型付け言語よりも多くなってしまうんじゃないかと思います。C++ ならコンパイラが自動的に検出する型の不整合チェックを,自分で書く必要があるわけで,そこにバグが入る余地もある。

しかし,まぁこれは書きゃいい話なので,手間だけれどプロジェクトが進まないほど致命的な話じゃありません。

一方で,あたしがどうしても気になるのは,次の点,つまり「分業に適したモジュールを作成できるか」という点です。限られた期間と予算で行う大規模開発の場合,少人数で開発することはまず不可能だし,論理的にも複数のサブシステム間で連携するのが普通だったりします。つまり,個々のサブシステム(コンポーネント)が,それぞれの API を通じて通信するわけですけれど,この API を適切に定義することができるのか,疑問なわけです。

特に,こうしたシステムを委託(受託)で作る場合,すべてのサブシステムを1つのベンダが請け負って実装することは,あまりありません(上流は別だが)。つまり,○○社は受発注システム,□□社は在庫管理のように,手分けして作るんですね。こうしたとき,どんなインターフェイスが用意されているか,適切に定義されていないと,各社間の調整が取れずに現場がかなり混乱します。

Java だったら,インターフェイスだけ持ったスタブライブラリ(中身が空っぽのライブラリ)を先に提供してもらえば,プロトタイプから使い方を推測できるし,それを使って自分のところの結合試験まで終わらせてしまう,とかいったことができます。Ruby でもおそらくできるんだろうけれども,型判定が緩すぎてスタブになりきれないことがあるんじゃないだろうか。

しかしおそらく,これは Ruby がダメという話なのではなくて,Java の開発スタイルを Ruby に無理矢理当てはめているからとも言えそうです。その意味で言えば,Ruby を初めとした LL が大規模開発に参入するには,大規模開発に対する独自のアプローチを提言する必要があるようにも思えます。今のところ,Web アプリのフレームワークといっても,Rails ができるのは紙芝居程度だし,それ用のワークフローが確立しているわけでもありません。やってやれないことはないんだろうけれども,リスクが高くて怖すぎる,というのが本音のところ。

しつこく書きますけど,あたしゃここで LL がダメだ,という話をしているわけじゃありません。もし LL で書くなら,どうしたことがネックになるのか考えると,なかなか一筋縄ではいかないな……とか云々。

Trackback
Trackback URL:
Ads
About
Search This Site
Ads
Categories
Recent Entries
Log Archive
Syndicate This Site
Info.
クリエイティブ・コモンズ・ライセンス
Movable Type 3.36
Valid XHTML 1.1!
Valid CSS!
ブログタイムズ

© 2003-2012 AIAN