Linuxビボ〜ろくより。
greenteaさんが 「GUIでは継承を使わない」って書いたことが発端です。
で、その中でgreenteaさんは
継承を多用することについての戒めとしては「オブジェクト指向スクリプト言 語 Ruby」でも「継承は最後の武器だ」と述べられています。
と述べておられます。
確かに私は『4756132545』の中で、 「継承は最後の武器だ」と書きましたが(p.219, p.562)、別に継承を避けろというつもりはないのです。
例によって私の表現が安易だったのですが、この機会に補足説明させてください。
まず、元ネタから説明しましょう。この言葉の元となった「拳銃は最後の武器だ」というセリフは、 『忍者部隊月光』の劇中で多用されるのですが、 実際には拳銃はばんばん使われてます。 ですから、意図としては「使うな」ではなく、「使う前に考えろ」です。
さて、技術的な点から考えると、greenteaさんも引用しているように 「継承はカプセル化の概念を破壊する」 あるいは「クラス継承よりもオブジェクトコンポジションを多用すること」 とはよく言われます。
しかし、私は同意しません。
(ちゃんと考えた後でも)継承を使いたくなるケースでは、 オブジェクトコンポジションの方が継承よりも優れていることはまれだからです。 むしろ、明示的な委譲の定義が繁雑で、「こんなこと自分でしなくちゃいけないのは変だ」と感じます。 そんなことを言語に押しつけて自動で片付けるための仕組みが、 オブジェクト指向言語の継承機能であったはずです。
「継承はカプセル化の概念を破壊する」件については、また別にもう少し考えなければなりません。 なぜ継承がカプセル化の概念を破壊するかといえば、 サブクラスはインスタンスの構造に直接触ることができるからです。
インスタンス変数を直接参照すれば、スーパークラスの実装に強く依存してしまいますし、 インスタンス変数を直接更新すれば、インスタンスの不整合な状態を作り出すことができます。 確かにこれはカプセル化の原則に対立します。
しかし、スーパークラスで定義されたインスタンス変数に直接触ることができることは、 オブジェクト指向言語にとって必須ではありません。たとえばC++はprivateなメンバには サブクラスからもアクセスすることができません。そしてさいわいなことにprivateがデフォルトです。 これが私の考えるC++の唯一優れた点なのですが。
Rebecca Wirfs-Brock女史は1988年のOOPSLAの論文でResponsibility Driven Designについて述べています。
その論文の中で、クラスの利用者は
の三種類があり、それぞれに見せるべき視点が異なると述べています。C++のpublic, private, protectedは まさにこの三種類に対応しているのです。余談ですが、去年のOOPSLAで会った時にWirfs-Brock女史のサインをもらってきました。彼女のファンなんです(ミーハー)。
結局問題なのはRubyのような言語がスーパークラスのインスタンス変数に簡単に触れてしまうという 「言語上の欠陥」なのであって継承そのものの問題ではないのですよね。 Rubyの次の世代の言語はぜひ「インスタンス変数はクラスローカル」が常識になってもらいたいものです。 事実、Perl6ではそうなるってDamian Conwayが言ってました。
というわけで、私の言葉を引いて継承を使わないほうがよいというのは、 私の本意とは違うんだ、ということです。
最後にどんな継承がまずいのか、あるいは不要なのか、について述べておきます。
私個人が継承を用いるかどうかについての唯一絶対のルールは「is-aの関係にあるか」です。 この関係が成立しない時に継承を使うのは純粋に間違いです。
では、この話の出発点に戻って「GUIに継承を用いるべきか」ですが、 ケースバイケースとしか言いようがありません。 ただ、
場合には遠慮無く使った方が良いと思うのです。ちゃんと考えた後でね。
始まったらしい。 レポートを見る限り、 かなり楽しそうだ。私も参加したいなあ(年寄りは引っ込みなさい)。
その後は参加者の自己紹介が簡単に行われたが、サーバ管理経験を持つ参加者が約半数を占めたほか、「前日にMosquito(1FD Linux)でルータを構築していたら遅刻しそうになった」と語る女の子や「(JIPDECの主催する)プログラミングコンテストの〆切と重なってしまいほとんど寝ていない」という男子など、さすが書類選考を突破してきただけあって濃い経験を持つ猛者がごろごろ現れており、今回の合宿の成果に期待できそうな印象を受けた
若者が頑張っている様子は頼もしい。ちゅーか、プロコンにも参加してくれるのね。 一生懸命審査します。
で、ぼこぼこにされると。
実際、akrさんからは結構なツッコミをいただいたわけだが、 険悪なものではなかった。
覚えていること
なんかもっと話したと思うんだけど、あんまり覚えていないなあ。
で、名古屋に着いたら6日土曜日の16時だった。 1日損した気分。
名古屋空港から米子までNH1843。よく見比べるとDASH8 series 300よりは フォッカー50の方が少し大きいし、作りもちょっとだけ高級な気がした。
自家用車に乗り換えて帰宅。
元々ヒゲを生やしていたのは
だが、OSCON2005も終わり、当面海外に行く予定はないわけだし、 私のヒゲに関わりなくRubyが成功しそうな様子も見届けた。
ま、もういいかな、と思って。でも、やっぱり誰も気づかない。
寝坊した。あやうく遅刻しそうなタイミングで教会へ。
ごく普通の日曜。日曜学校の時間は託児クラスの補助に入る。 が、ここ子供たちは手がかからないので(一人は末娘だし)、 苦労はなかった。
集会終了後、人待ちがあったり、いろいろで遅くなる。 先に帰った妻がすっかりくたびれている。 幼い子供がえらくにぎやかだったらしい。
それはそれは。
Groovyの(Javaにない)演算子について。
「*.」や「.@」についてはどこまでうれしいのかよく分からないけど、 レシーバがnilならnilを返すメソッド呼び出し「?.」や、 メソッドを取り出す「.&」は、ちょっと欲しいと本気で思った。
しかし、よく考えないと「.」が前に来るのか、後に来るのか すぐにわからなくなってしまいそうだ。
LL魂のLightning Talkで発表された Ruby, Perl, Python, PHP, JavaScriptで動作する 高速テンプレートエンジン。
っていうか、DjangoやKidがそんなに遅いとは知らなかった。 ってことは、テンプレートエンジンの性能差というのが 全体のパフォーマンスに与える影響はわずかということなのだろうか。
CによるCPS (Continuation Passing Style) の実装っていうすごく面白そうな内容の論文[PDF]。 まだ読んでない。
YARVのFiberやブロックの高速化とかに使えるんだろうか。 なんとなく難しそうな気がするけど。
Lockすることなしにプロセス間通信を行うアルゴリズムについて。
アルゴリズム1,2くらいまではなにを言ってるか分かるんだけど、 コードが断片的すぎて(私の知識が限定的すぎて)、 どのくらいうれしいのか、どのくらい画期的なのか判断できなかった。
プロセス間通信のコストが下がるのであれば、 それに越したことはないのだけれど。
Pythonにおいて、マルチコアやクラスタを最大限活用しようと言う試み。
大変素晴らしい。で、将来参考にできるものがあれば ぜひ参考にさせてもらおう。
サンプルを見る限り、APIはちょっとわかりにくい気がする。 が、使い方が全然想像もつかないほどではない。
Googleの中にいれば、幸せだろうということは想像できる。 が、同時に外との断絶も発生しそうだ。
すべての人がGoogleの「中の人」になれない以上、 その幸せは人類の幸せではない。 それでいいのだろうか。
いいのか。
いや、FUDなのは分かってるんだ。 Googleにスポンサーされているオープンソースプロジェクトは沢山あるし、 Googleから公開されているものだってある。
でも、それでもなお私は自分の不安が消せない。
帰省している間、ネットから隔絶されているので、 この機会に「いつか手をつけようと思ってた問題」を片づけよう。
ふたつのオブジェクトのエンコーディングに互換性があるかどうかをチェックする関数 rb_enc_checkだが、Rubyのソースコード全体に19箇所登場しているすべてが ふたつの文字列のエンコーディングを比較していた。
ということは、文字列専用のチェックにすればもっと高速化するのでないだろうか。
そう思って試してみたのだが、 測定する限りでは誤差の範囲内しか効果がないようであった。
US-ASCII文字列は本来7bitの範囲内の文字しか含まないはずなので、 これを利用するとcoderangeチェックが節約できるはず。
と思ったが、測定結果これまた効果なし。
Integer#to_sの結果はいつもUS-ASCIIでcoderangeは7bitに決まっている。 ので、あらかじめ7bitフラグを立てることを考えてみた。 が、よっぽど長い文字列(すごく大きな整数)を取り扱わない限り、差はないようである。
現在、Ruby 1.8の動作とRuby 1.9でClass.dupを行った時の 定数、クラス定数の振る舞いが異なる。
で、1.9の動作(つまり昔の1.8の動作)が正しいと思っていたのだが、 この機会にいろいろ考えてみたら、やっぱり1.8の動作が望ましいが、 現在の1.8にはバグがある(バグを直した動作が「正しい」)ということが 分かった。
で、1.8ではその「バグ」を直したのだが、 問題は1.9でこの挙動をどうやって実現すればよいのかわからないことだ。
かなり長い時間ソースコードを解析して、 Methodが指しているiseqがcref_stackを持っていることが分かったので、 対策としては
などを考えついたが、実際に動かすところまでには持っていけなかった。
今回は時間はかかった(休みだから余裕はあった)が、 成果はほとんどなかった。残念
姪っ子と うちの子供たちを連れて山口市の「ちょうちん祭」にでかける。 今回の帰省の最大の目的でもある。
娘たちの浴衣姿とかとてもかわいらしかった。
人ごみは苦手だけど、祭りならなんとか耐えられるかな。