From: Yusuke ENDOH Date: 2010-11-07T18:02:45+09:00 Subject: [ruby-list:47617] Re: Rubyでも「private」イコール「非公開」? 遠藤です。 2010年11月6日13:12 Makoto Kuwata : >>> 逆に公開したくないんだけどレシーバつけて呼び出すから >>> privateはつけられないようなメソッドもあります。 >> >> C++ の friend が欲しいケースですかね。これは別の問題だと思います。 > > 別にfriendのことではないです。自分のクラスでしか使わないから非公開に > したいけど、レシーバは省略しないケースを想定しています。 ここは protected で如何でしょうか。 class Node def inspect2 # for debug buf = '' level = 0 _inspect2(buf, level) buf end def _inspect2(buf, level) buf << (' ' * level) << '- ' << @value.inspect << "\n" @left_node._inspect2(buf, level+1) @right_node._inspect2(buf, level+1) end protected :_inspect2 end @left_node が Node クラスのインスタンスとは限らない場合には、 メソッドを二段構えにする必要がありそうです。 module Inspect2able def inspect2 # for debug buf = '' level = 0 _inspect2(buf, level) buf end def _inspect2(buf, level) _inspect2_core(buf, level) end protected :_inspect2 end class Node include Inspect2able def initialize(v, l, r) @value, @left_node, @right_node = v, l, r end def _inspect2_core(buf, level) buf << (' ' * level) << '- ' << @value.inspect << "\n" @left_node._inspect2(buf, level+1) @right_node._inspect2(buf, level+1) end private :_inspect2_core end class Leaf include Inspect2able def _inspect2_core(buf, level) end private :_inspect2_core end puts Node.new(1, Node.new(2, Leaf.new, Leaf.new), Node.new(3, Leaf.new, Leaf.new)).inspect2 >> 目的: 使ってほしくないことを伝えたい (普通には使えなくしたい) >> 手段: レシーバを指定した呼び出しを禁止する > > が妥当かどうか、というのがポイントなのかなと思います。 > #いちおうここでは「非公開」=「使ってほしくない」という意味で考えてます。 > つまり、レシーバつきの呼び出しを禁止することが、Rubyでは「非公開(使って > ほしくない)」を意味するかどうかです。 > 結局は上の分類にあったように、privateでも公開されているものがあるから、 > 「privateだからといって必ずしも非公開を意味するわけではない」という、 > あまりすっきりしない結論になっちゃうと思います。 まあ、実用上は混乱することはないように思います。 「非公開」の意味についてはまつもとさんが否定しているみたいなので、 これ以上の議論は無意味かもですが。 -- Yusuke Endoh