«前の日(08-05) 最新 次の日(08-07)» 追記

Matzにっき


2003年08月06日

_ [OOP]継承は悪か

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に継承を用いるべきか」ですが、 ケースバイケースとしか言いようがありません。 ただ、

  • 今作ろうとしているエンティティが既存のクラスのis-aである
  • 継承を使った方が楽ができる

場合には遠慮無く使った方が良いと思うのです。ちゃんと考えた後でね。


2004年08月06日 広島・原爆の日

_ [会社]東京

出張。かなりむりやりな感じもするが、今後の仕事につながるかもしれない打ち合わせ。

あとは秋葉原をちょっと歩いたり。

_ 若者たちの熱い夏、始まる - セキュリティキャンプ 2004が開始

始まったらしい。 レポートを見る限り、 かなり楽しそうだ。私も参加したいなあ(年寄りは引っ込みなさい)。

その後は参加者の自己紹介が簡単に行われたが、サーバ管理経験を持つ参加者が約半数を占めたほか、「前日にMosquito(1FD Linux)でルータを構築していたら遅刻しそうになった」と語る女の子や「(JIPDECの主催する)プログラミングコンテストの〆切と重なってしまいほとんど寝ていない」という男子など、さすが書類選考を突破してきただけあって濃い経験を持つ猛者がごろごろ現れており、今回の合宿の成果に期待できそうな印象を受けた

若者が頑張っている様子は頼もしい。ちゅーか、プロコンにも参加してくれるのね。 一生懸命審査します。

_ [Ruby]まつもとを取り囲む会

で、ぼこぼこにされると。

実際、akrさんからは結構なツッコミをいただいたわけだが、 険悪なものではなかった。

覚えていること

  • 「好きなメソッドはString#eachです」
  • Process.daemonメソッドを(/dev/nullをどうする?)
  • mknod, mkfifoを(環境ごとの違いを吸収する?)
  • strftimeに%zを標準実装
  • 「新パーザはどうなってるんですか」「年内には完成しません、というかあきらめ気味」
  • ripperを1.9に取り込む
  • wrapしてevalする関数(後で調べたらeval_string_wrapはもうあった)
  • 子供にコンピュータ(or ゲーム)を与えるか
  • ハッカーの育て方
  • 「アセンブラを理解しないとコンピュータは理解できない」対「抽象度の高い理解で十分」。
  • 「ポインタをアセンブラで理解する」対「ポインタをLispで理解する」
  • ナイコン(死語)が「頭の中でCPUを動かした」と「頭の中で言語を動かした」とは違うらしい
  • YARVをどう作る
  • モデレーション付きアンテナ、日記ランキング。はてなアンテナで十分?
  • 「RubyでGaucheを実装する」「RubyでSchemeじゃないの?(なら、Ruchemeがある)」「いや、Gaucheは独立した言語だから」

なんかもっと話したと思うんだけど、あんまり覚えていないなあ。


2005年08月06日

_ 名古屋着

で、名古屋に着いたら6日土曜日の16時だった。 1日損した気分。

名古屋空港から米子までNH1843。よく見比べるとDASH8 series 300よりは フォッカー50の方が少し大きいし、作りもちょっとだけ高級な気がした。

自家用車に乗り換えて帰宅。

_ ヒゲを剃る

元々ヒゲを生やしていたのは

だが、OSCON2005も終わり、当面海外に行く予定はないわけだし、 私のヒゲに関わりなくRubyが成功しそうな様子も見届けた。

ま、もういいかな、と思って。でも、やっぱり誰も気づかない


2006年08月06日

_ 日曜

寝坊した。あやうく遅刻しそうなタイミングで教会へ。

ごく普通の日曜。日曜学校の時間は託児クラスの補助に入る。 が、ここ子供たちは手がかからないので(一人は末娘だし)、 苦労はなかった。

集会終了後、人待ちがあったり、いろいろで遅くなる。 先に帰った妻がすっかりくたびれている。 幼い子供がえらくにぎやかだったらしい。

それはそれは。


2007年08月06日

_ [言語] uehajの日記 - Groovyの奇妙な演算子(その1)

Groovyの(Javaにない)演算子について。

「*.」や「.@」についてはどこまでうれしいのかよく分からないけど、 レシーバがnilならnilを返すメソッド呼び出し「?.」や、 メソッドを取り出す「.&」は、ちょっと欲しいと本気で思った。

しかし、よく考えないと「.」が前に来るのか、後に来るのか すぐにわからなくなってしまいそうだ。

_ [言語] Tenjin

LL魂のLightning Talkで発表された Ruby, Perl, Python, PHP, JavaScriptで動作する 高速テンプレートエンジン。

っていうか、DjangoやKidがそんなに遅いとは知らなかった。 ってことは、テンプレートエンジンの性能差というのが 全体のパフォーマンスに与える影響はわずかということなのだろうか。

_ [言語] HAL - CNRS

CによるCPS (Continuation Passing Style) の実装っていうすごく面白そうな内容の論文[PDF]。 まだ読んでない。

YARVのFiberやブロックの高速化とかに使えるんだろうか。 なんとなく難しそうな気がするけど。

_ Dr. Dobb's | Lock-free Interprocess Communication

Lockすることなしにプロセス間通信を行うアルゴリズムについて。

アルゴリズム1,2くらいまではなにを言ってるか分かるんだけど、 コードが断片的すぎて(私の知識が限定的すぎて)、 どのくらいうれしいのか、どのくらい画期的なのか判断できなかった。

プロセス間通信のコストが下がるのであれば、 それに越したことはないのだけれど。

_ [言語] Parallel Python

Pythonにおいて、マルチコアやクラスタを最大限活用しようと言う試み。

大変素晴らしい。で、将来参考にできるものがあれば ぜひ参考にさせてもらおう。

サンプルを見る限り、APIはちょっとわかりにくい気がする。 が、使い方が全然想像もつかないほどではない。

_ Googleは人材を飲み込むブラックホールか − @IT

Googleの中にいれば、幸せだろうということは想像できる。 が、同時に外との断絶も発生しそうだ。

すべての人がGoogleの「中の人」になれない以上、 その幸せは人類の幸せではない。 それでいいのだろうか。

いいのか。

いや、FUDなのは分かってるんだ。 Googleにスポンサーされているオープンソースプロジェクトは沢山あるし、 Googleから公開されているものだってある。

でも、それでもなお私は自分の不安が消せない。


2008年08月06日

_ 夏休み

帰省している間、ネットから隔絶されているので、 この機会に「いつか手をつけようと思ってた問題」を片づけよう。

rb_enc_check

ふたつのオブジェクトのエンコーディングに互換性があるかどうかをチェックする関数 rb_enc_checkだが、Rubyのソースコード全体に19箇所登場しているすべてが ふたつの文字列のエンコーディングを比較していた。

ということは、文字列専用のチェックにすればもっと高速化するのでないだろうか。

そう思って試してみたのだが、 測定する限りでは誤差の範囲内しか効果がないようであった。

US-ASCII文字列のcoderange

US-ASCII文字列は本来7bitの範囲内の文字しか含まないはずなので、 これを利用するとcoderangeチェックが節約できるはず。

と思ったが、測定結果これまた効果なし。

rb_big2str0結果のcoderange

Integer#to_sの結果はいつもUS-ASCIIでcoderangeは7bitに決まっている。 ので、あらかじめ7bitフラグを立てることを考えてみた。 が、よっぽど長い文字列(すごく大きな整数)を取り扱わない限り、差はないようである。

Class.dupの動作

現在、Ruby 1.8の動作とRuby 1.9でClass.dupを行った時の 定数、クラス定数の振る舞いが異なる。

で、1.9の動作(つまり昔の1.8の動作)が正しいと思っていたのだが、 この機会にいろいろ考えてみたら、やっぱり1.8の動作が望ましいが、 現在の1.8にはバグがある(バグを直した動作が「正しい」)ということが 分かった。

で、1.8ではその「バグ」を直したのだが、 問題は1.9でこの挙動をどうやって実現すればよいのかわからないことだ。

かなり長い時間ソースコードを解析して、 Methodが指しているiseqがcref_stackを持っていることが分かったので、 対策としては

  • iseqをコピーしてcref_stackを書き換える
  • cref_stack以外は元のiseqを参照するという特別なiseqを作る
  • メソッドのcref_stackトップをiseqではなく、NODE_METHODから取る

などを考えついたが、実際に動かすところまでには持っていけなかった。

まとめ

今回は時間はかかった(休みだから余裕はあった)が、 成果はほとんどなかった。残念

_ 山口ちょうちん祭

姪っ子と うちの子供たちを連れて山口市の「ちょうちん祭」にでかける。 今回の帰省の最大の目的でもある。

娘たちの浴衣姿とかとてもかわいらしかった。

人ごみは苦手だけど、祭りならなんとか耐えられるかな。


«前の日(08-05) 最新 次の日(08-07)» 追記