编写Ruby库 - 从模块外部隐藏方法

时间:2010-05-24 15:56:30

标签: ruby class module

我正在编写一个Ruby库,里面有一堆包含类的模块。其中许多类需要通过调用脚本来使用和修改,但我不希望(某些)初始化器可见/可调用:

module MyLib
  class Control
    def initialize
      # They can use this
    end

    def do_stuff
      Helper.new('things')
    end
  end

  class Helper
    # Shouldn't be visible 
    def initialize(what)
      @what = what
    end

    def shout
      @what
    end
  end
end

c = MyLib::Control.new
h = c.do_stuff
p h.shout
# => "things"
# ^ All of this is desired

# v This is undesirable
p MyLib::Helper.new('!')
# => <MyLib::Helper @what='!'>

如果这是一件简单的事情,那么我也很欣赏生成的RDoc甚至不包括.new类的Helper方法。有什么想法吗?

感谢阅读!

2 个答案:

答案 0 :(得分:3)

正如@Matthew指出的那样,我原来的答案是完全错误的。但还有其他解决方法。例如,您可以将匿名类分配给Control上的类变量,并使用class_eval仍然将方法定义为正常:

module MyLib
  class Control
    def initialize
    end

    def do_stuff
      @@helper.new('things')
    end

    @@helper = Class.new
    @@helper.class_eval do
      def initialize(what)
        @what = what
      end

      def shout
        @what
      end
    end
  end
end

摘录

c = MyLib::Control.new
h = c.do_stuff
p h.shout

仍然写"things",但现在除了通过类变量之外无法访问@@helper。如果某人真的想要访问它,我重新打开Control课程或使用class_eval,就没有什么可以阻止他们了,但这只是你必须用动态语言来处理的事情

我选择将匿名类分配给一个类变量,以便只创建一次;但如果您不关心多次重新定义匿名类,则没有理由它不能成为实例变量。

答案 1 :(得分:2)

Ruby有access control