How to implement a private inner class in Ruby

Starting with Java, I am trying to implement LinkedList in Ruby. The usual way to implement this in Java is with a class called LinkedList and a private inner class called Node with each LinkedList object as a Node object.

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

I do not want to disclose the Node class to the outside world. However, with this setting in Ruby, I can access the private object of the Node class outside the LinkedList class using this -

node = LinkedList::Node.new

I know that with Ruby 1.9 we can use the private_constant method to designate Node as a private constant. But I wonder if this is the right thing to do? Also, why can I create Node objects outside the LinkedList class, even if it is declared as private?

+4
2

Node LinkedList, ?

"" . , , . , 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
+8

, , :

Ruby

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

, Node

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

LinkedList singleton:

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

private_constant, .

+3

Source: https://habr.com/ru/post/1655920/


All Articles