From: keiju@... (=?ISO-2022-JP?B?GyRCQFBETTc9PHkbKEI=?=) Date: 2008-09-02T20:33:41+09:00 Subject: [ruby-dev:36103] Re: 1.9と1.8で、delegateのインスタンスのクラス名の違う けいじゅ@いしつかです. In [ruby-dev :36024 ] the message: "[ruby-dev:36024] Re: 1.9と1.8で、 delegateのインスタンスのクラス名の違う ", on Aug/28 01:40(JST) "U.Nakamura" writes: >こんにちは、なかむら(う)です。 どもどもです. 相変わらずの遅メイルで申し訳ない. >正しい継承とはなんぞや、という話は石塚さんにしていただいた方 >がいいと思うので私が書いちゃうと釈迦に説法なわけですが ^^;、 釈迦に説法だなんて, 私は煩悩の塊ですので, まだまだお釈迦様にはなれませ ん(^^; >汎化<->特化の関係にあるクラス同士を結びつけるのが正しい継承な >のだろうと私は理解しています。 そうですね. >で、継承を使わずに委譲を使うというのは、本来は委譲元と委譲先 >は継承関係にないから委譲を使っているはずなわけです。 >にもかかわらず、Rubyで委譲を使うと表面的には継承関係にあるか >のように見えてしまうのはよろしくないのではないか、と考えてい >ます。 うーん. たしかにその通りかも知れないです. (概念的には)継承は 委譲の一種であって, 委譲は継承の一種ではないですか らねぇ. > あ、kind_of?で見てたら継承じゃなくて委譲を使われていたから > 動かなかったよ。 > ここはrespond_to?でメソッドを呼べるかチェックすべきだったん > だなあ。 >という方向に行くことを期待したいのですが、ダメですかね。 これが正しい方向かも. rubyってタイプスイッチを構文的にサポートしている感じなので, つい使って しまいがちですよね. あれっていうのは, duck type 的にはあまりよろしくな かったのかもしれませんねぇ. ただ, case obj when Klass とか, kind_of?にしても, 継承関係を聞いているのではなく, 実はまとめて resopnd_to?したい場合が多い気がするので, それを判断する専用のメソッド があると良いかもしれません. obj.same_response?(mod) とか, case obj when same_response(mod) .... とかね. In [ruby-dev :36059 ] the message: "[ruby-dev:36059] Re: 1.9と1.8で、 delegateのインスタンスのクラス名の違う ", on Aug/30 22:58(JST) "Keita Yamaguchi" writes: >山口と申します。 Delegator#classに関しては 1.8 でよい気になりましたので, こちらにはちょっとだけ. > 以上に挙げた三点は基本的に C で rb_obj_is_kind_of を > 呼び出しているために起きる現象であると思います。 > DelegateClass を用いて #kind_of? を委譲したとしても > こうしたものに関してはどうしても無力ですので、 > 拡張ライブラリにおいても同様に問題になる可能性があります。 そのとおりですね. delegatorのために全部変えろと言うのも現実的でないで しょうね. あと, > エラーメッセージがややこしいことになります。 については, 同意することで, DEBUGフラグがたっているときは少なくとも, Delegator#inspect は delegatorであることが分かるようになっている方が良 い気がします. 以下の感じです -- emperor2% ruby-dev -S irb -r lib/delegate.rb irb(main):001:0> SimpleDelegator.new([]) => [] irb(main):002:0> DEBUG=1 => 1 irb(main):003:0> SimpleDelegator.new([]) => # -- 勝手に変えるわけにも行かないので, 一応パッチを: --- lib/delegate.rb (リビジョン 19067) +++ lib/delegate.rb (作業コピー) @@ -117,7 +117,7 @@ class Delegator preserved = [ :__id__, :object_id, :__send__, :public_send, :respond_to?, :send, - :instance_eval, :instance_exec, :extend, + :instance_eval, :instance_exec, :extend, :class, :inspect, ] instance_methods.each do |m| next if preserved.include?(m) @@ -209,6 +209,14 @@ new.__setobj__(__getobj__.dup) new end + + def inspect + if defined?(DEBUG) && DEBUG + "#<#{self.class}: #{self.__getobj__.inspect}>" + else + self.__getobj__.inspect + end + end end include MethodDelegation end __ ---------------------------------------------------->> 石塚 圭樹 <<--- ---------------------------------->> e-mail: keiju@ishitsuka.com <<---