如何在 Ruby 中实现私有内部 class
How to implement private inner class in Ruby
来自 Java,我正在尝试在 Ruby 中实现 LinkedList。我在 Java 中实现它的通常方法是有一个 class 称为 LinkedList 和私有内部 class 称为 Node 与 LinkedList 的每个对象作为 Node 对象。
class LinkedList
private
class Node
attr_accessor :val, :next
end
end
我不想将节点 class 暴露给外部世界。但是,通过 Ruby 中的此设置,我可以使用此 -
访问 LinkedList class 之外的私有节点 class 对象
node = LinkedList::Node.new
我知道,在 Ruby 1.9 中,我们可以使用 private_constant 方法将 Node 指定为私有常量。但我想知道这是否是实现此目标的正确方法?另外,为什么我能够在 LinkedList class 之外创建 Node 对象,即使它被声明为私有?
why am I able to create Node objects outside the LinkedList class even though it is declared as private?
因为在 ruby 常量中忽略 "regular" 可见性修饰符。它们总是 public,无论它们在哪个部分。要将它们设为私有,请使用 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
我知道Sergio的回答绰绰有余,但只是回答问题:
How to implement private inner class in 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
的单例 class 常量中使用:
LinkedList.singleton_class.constants
#=> [:Node, :DelegationError, :RUBY_RESERVED_WORDS, :Concerning]
我通常使用private_constant
,但它是另一种方式来拥有私有class。
来自 Java,我正在尝试在 Ruby 中实现 LinkedList。我在 Java 中实现它的通常方法是有一个 class 称为 LinkedList 和私有内部 class 称为 Node 与 LinkedList 的每个对象作为 Node 对象。
class LinkedList
private
class Node
attr_accessor :val, :next
end
end
我不想将节点 class 暴露给外部世界。但是,通过 Ruby 中的此设置,我可以使用此 -
访问 LinkedList class 之外的私有节点 class 对象node = LinkedList::Node.new
我知道,在 Ruby 1.9 中,我们可以使用 private_constant 方法将 Node 指定为私有常量。但我想知道这是否是实现此目标的正确方法?另外,为什么我能够在 LinkedList class 之外创建 Node 对象,即使它被声明为私有?
why am I able to create Node objects outside the LinkedList class even though it is declared as private?
因为在 ruby 常量中忽略 "regular" 可见性修饰符。它们总是 public,无论它们在哪个部分。要将它们设为私有,请使用 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
我知道Sergio的回答绰绰有余,但只是回答问题:
How to implement private inner class in 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
的单例 class 常量中使用:
LinkedList.singleton_class.constants
#=> [:Node, :DelegationError, :RUBY_RESERVED_WORDS, :Concerning]
我通常使用private_constant
,但它是另一种方式来拥有私有class。