Writing Ruby Libraries - Hiding Methods from the Module Outside

I am writing a Ruby library that has a module with a bunch of classes inside it. Many of these classes need to be used and modified by calling scripts, but I do not want (some of) initializers to be visible / callable:

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='!'> 

If this is a simple thing, then I would also like the generated RDoc not even to include the .new method for the Helper class. Any ideas?

Thank you for reading!

+4
source share
2 answers

My initial answer was completely wrong, as @Matthew pointed out. But there are other workarounds. For example, you can assign an anonymous class to a class variable on Control and still define methods as usual using 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 

Excerpt

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

still writes "things" , but now there is no way to access @@helper , except through a class variable. If someone really wants to access it, I open the Control class again or use class_eval , nothing can be stopped there, but this is just what you have to deal with in a dynamic language.

I decided to assign an anonymous class to a class variable so that it was created only once; but if you don't care about overriding the anonymous class many times, there is no reason why it cannot be an instance variable.

+3
source

Ruby has access control .

+2
source

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


All Articles