Ruby模块中的私有类(不是类方法)?

我是Ruby的新手(熟悉Python,C ++和C)。 我需要创建一个只能由模块中的其他类和方法使用的类。 在Python中,我只是将其称为__classname。 我在C ++中使用了一个空的typedef。 我如何在Ruby中执行此操作(或者我是在咆哮错误的树而不是以“Ruby方式”执行此操作?)

到目前为止我还没有在Ruby中看到过这样的概念,但是我想你可以通过创建私有方法来模拟它,这将返回一个创建为局部变量的类(请记住,在Ruby中,类是一个对象,就像任何其他类一样,并且可以在方法中实例化并由它返回)。

顺便说一句,即使Ruby中的私有方法也不像其他语言那样私密 – 你总是可以使用send方法访问它们。 但这样做意味着你知道自己在做什么。

最重要的是要认识到一个class级并不特别。 这只是一个对象。 按照惯例,类被分配给常量,但没有任何东西可以说是必须的。

由于类只是像任何其他对象一样的对象,因此您将它们设置为私有,就像将任何其他对象设为私有一样。

以下是我可以想到的可能性,按照增加私密性的顺序:

  1. 只需将它们嵌套在命名空间(即模块)中。 在Ruby中,通常期望所有库的模块和类都存在于与库名称相同的命名空间内(即my_awesome_libraryMyAwesomeLibrary ),但一般来说,嵌套在该命名空间下的所有内容都被视为私有。 事实上,除了Test::Unit::TestCase ,我想不出客户端代码实际预期会使用的三级深命名空间的单个示例。
  2. 与1.相同,但将其命名为明显的,如MyAwesomeLibrary::Internal::FfiStruct
  3. 与1.或2.相同,并使用:nodoc: RDoc标记进行标记。
  4. 类似于3.,但使用更现代的文档系统,如YARD,它实际上允许您明确标记私有API。
  5. 使用方法而不是常量。 方法可以私有化。 (为了保持一致性,您可以让方法名称以大写字母开头,使其类似于常量。没有什么可以阻止的, snake_case约定就是:一个约定。)
  6. 使用实例变量。 他们总是私密的。 请注意,可以使用reflection轻松访问私有方法和实例变量。 然而, send似乎比instance_variable_get更广泛使用,这就是为什么我认为实例变量具有比方法更高级别的隐私。
  7. 实际上,获取实际隐私或封装的唯一方法是使用局部变量和闭包。 但请注意,这可能会妨碍您使用Ruby的模块,类或方法定义语法,因为这些会创建新的范围。 在您需要访问类的所有情况下,您需要使用Module.newClass.newModule#define_method

例:

 module MyAwesomeLibrary struct = Class.new(FFI::Struct) do # ... end PublicInterface = Class.new do define_method(:initialize) do |bar| @foo = struct.new(bar) end end end 

是的,这是在Ruby中实现真正的100%信息隐藏和封装的唯一方法。

但是,正常的Ruby方式是简单地将这些东西记录为私有(可能会将其命名为命名空间),并相信您的开发人员。 在Ruby社区中,有时会在Python口号“我们都同意成年人”中对此进行总结。

直接从这篇博客文章中获取这些信息 ,但是从Ruby 1.9.3开始,您可以使用private_constant在模块中创建一个私有类:

 class Person class Secret def to_s "1234vW74X&" end end private_constant :Secret def show_secret Secret.new.to_s end end