2016-09-27 24 views
3

Javaから来て、私はRubyでLinkedListを実装しようとしています。これをJavaで実装する通常の方法は、LinkedListという名前のクラスと、LinkedListの各オブジェクトをNodeオブジェクトとするNodeという専用の内部クラスです。Rubyでプライベート内部クラスを実装する方法

class LinkedList 
    private 
    class Node 
    attr_accessor :val, :next 
    end 
end 

私は外部の世界にNodeクラスを公開する必要はありません。しかし、Rubyでこの設定で、私はこれを使用してLinkedListのクラスの外にプライベートNodeクラスのオブジェクトにアクセスすることができます -

node = LinkedList::Node.new 

私が知っている、ルビー1.9で、我々はプライベート定数としてノードを指定するprivate_constantメソッドを使用することができます。しかし、これがこれを達成する正しい方法であるかどうか疑問に思っていますか?また、プライベートとして宣言されているにもかかわらず、LinkedListクラスの外にあるNodeオブジェクトを作成できるのはなぜですか?

+2

ルビーではガラスの家に住んでいるので、いつもあなたのプライベートなものを見ている人に慣れてください。あなたが管理できる最高のものは、人々がアイデアを得るのを避けるようになるという丁寧な方法として、「しないでください」と言います。 – tadman

+0

ところで、あなたの質問に答えるか、あなたの問題を解決する答えを受け入れるべきです。回答の左側にある緑色のチェックマークを探します。 –

答えて

7

私は、プライベートとして宣言されていてもLinkedListクラスの外にNodeオブジェクトを作成できますか?

ルビ定数では、「通常の」可視性修飾子を無視するためです。彼らはどのセクションに属していても常に公開されています。プライベートにするには、private_constantを使用してください。この控えめなデザインや何かを呼びなさい、それはそうです。

また、private_constantであっても、機密性はごくわずかであることに注意してください。基本的には、リスト(LinkedList.constants)と直接解像度(LinkedList::Node)から定数を隠すことだけです。名前を知っていれば、にアクセスできます。

class LinkedList 
    class Node 
    attr_accessor :val, :next 
    end 

    private_constant :Node 
end 

LinkedList.const_get('Node') # => LinkedList::Node 
+0

私は 'node = LinkedList :: Node.new'のようなものを' private_constant'と一緒に使うことはできないと思います。 –

+0

@BartekGładys:はい、それは私が言っていたことです。 –

+0

オクラホマ、それはかなりです:) –

3

私はセルジオの答えは十分以上であることを知っているが、ちょうど質問に答える:あなたはで行くことができルビー

をプライベート内部クラスを実装する方法を

を:

class LinkedList 
    class << self 
    class Node 
    end 

    def some_class_method 
     puts Node.name 
    end 
    end 
end 

LinkedList.some_class_method  # accessible inside class 
#=> #<Class:0x007fe1e8b4f718>::Node 
LinkedList::Node     # inaccessible from outside 
#=> NameError: uninitialized constant LinkedList::Node 
LinkedList.const_get('Node')  # still inaccessible 
#=> NameError: uninitialized constant LinkedList::Node 

もちろん、

LinkedList.singleton_class::Node 
#=> #<Class:0x007fe1e8b4f718>::Node 

NodeにアクセスすることができるだろうそしてそれはまたLinkedListのシングルトンクラス定数内で提供されています:

LinkedList.singleton_class.constants 
#=> [:Node, :DelegationError, :RUBY_RESERVED_WORDS, :Concerning] 

私は通常private_constantを使用しますが、それが持っているもう一つの方法でありますプライベートクラス。

+0

これはうまく見えますが、これも簡単に回避できます: 'LinkedList.singleton_class :: Node#=>#<クラス:0x007f899f82b1c8> :: Node' :) –

+0

また、' LinkedList.singleton_class.constants#=> [: Node] ' –

+0

@SergioTulentsev正解。これはRubyで何も「アクセスできない」ということをもう一度確認します:) –

関連する問題