# "private" modules

**URL:** <https://www.ruby-forum.com/t/private-modules/180073>\
**Category:** Ruby\
**Created:** [December 10, 2009, 10:00pm UTC](https://www.ruby-forum.com/t/private-modules/180073 "2009-12-10T22:00:58Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [December 10, 2009, 10:00pm UTC](https://www.ruby-forum.com/t/private-modules/180073/1 "2009-12-10T22:00:58Z")

</div>

Hi,  
I’m writing a ruby library, under a module named “A”. Since I provide  
classes which share names with standard ruby classes (like Vector), this  
way I avoid namespace pollution when requiring my library.  
The problem is that I have an inner (“private”) module “B”, defined  
under “A” where I have a bunch of methods defined that these classes  
will use (I’m using RubyFFI).

But, since (as a user of my library) I would want to “include A” to  
avoid the A:: prefix everywhere, the inner module “B” would be exposed  
to the top-level.  
I don’t think it may be really problematic, but I think it may be a  
common issue that others may face.

An example:

module A

# I provide a nice Vector implementation, to replace Ruby’s

class Vector  
def func  
# …  
B::c\_library\_func§  
# …  
end  
end

module B  
extend FFI::Library  
attach\_function :c\_library\_func, [:pointer], :void  
# and continues…  
end  
end

If I do:  
include A  
Now B is visible to the user, and it may end-up clashing with something  
else.

Is there a guideline for these cases?

Thank you

---

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [December 10, 2009, 11:19pm UTC](https://www.ruby-forum.com/t/private-modules/180073/2 "2009-12-10T23:19:57Z")

</div>

On 12/10/2009 10:01 PM, Matt B. wrote:

> to the top-level.  
> B::c\_library\_func§
> 
> If I do:  
> include A  
> Now B is visible to the user, and it may end-up clashing with something  
> else.
> 
> Is there a guideline for these cases?
> 
> Thank you

You might be able to pull this off with instance or local variables:

module A  
@b = Module.new # or b = …  
extend FFI::Library  
…  
end

Vector.send :include, @b  
end

# untested

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [December 11, 2009, 12:26am UTC](https://www.ruby-forum.com/t/private-modules/180073/3 "2009-12-11T00:26:02Z")

</div>

Oh, anonymous module, good idea.  
Anyway, since I don’t actually want to include stuff into Vector, I  
changed it to this:

module A  
@backend = Module.new do  
def self.bleh  
puts 1  
end  
end

def A.backend  
@backend  
end  
end

module A  
class Vector  
def initialize  
puts A.backend.class  
end  
end  
end

Since GSL.backend is a module method, when I do “include A” at the  
top-level, neither @backend nor A.backend are visible.  
It would be cool to have something like “private” for modules, so that  
modules defined after that keyword would only be accesible from the  
parent module.

In any case, I’m open to any other idea better than mine.

Matt

---

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [December 11, 2009, 4:52am UTC](https://www.ruby-forum.com/t/private-modules/180073/4 "2009-12-11T04:52:19Z")

</div>

On Dec 10, 4:01 pm, Matt B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> to the top-level.  
> B::c\_library\_func(p)
> 
> If I do:  
> include A  
> Now B is visible to the user, and it may end-up clashing with something  
> else.
> 
> Is there a guideline for these cases?

What is the use case of B? Is it only important to Vector or  
subclasses of it, then put it inside Vector.

Otherwise, probably nothing to worry about. You can’t clobber a  
constant by using include if it already exists.

> > module A  
> > module B  
> > def self.b; “B”; end  
> > def self.q; “Q”; end  
> > end  
> > end  
> > =\> nil  
> > module B  
> > def self.b; “B!”; end  
> > end  
> > =\> nil  
> > B.b  
> > =\> “B!”  
> > include A  
> > =\> Object  
> > B.b  
> > =\> “B!”  
> > B.q  
> > NoMethodError: undefined method `q’ for B:Module

---

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [December 11, 2009, 10:30am UTC](https://www.ruby-forum.com/t/private-modules/180073/5 "2009-12-11T10:30:01Z")

</div>

On Thursday 10 December 2009 05:26:03 pm Matt B. wrote:

> It would be cool to have something like “private” for modules, so that  
> modules defined after that keyword would only be accesible from the  
> parent module.

Hmm… I’m not sure that’s a good idea. Besides, the anonymous module  
seems  
like overkill. Maybe people will like your Vector class?

There’s really nothing stopping you from doing it like this:

module A  
module Private  
class Vector  
end

def foo  
Private::Vector.new  
end  
end

Keep in mind that if anyone actually needs to get at the original Ruby  
classes, they can always access ::Vector, or worst case, they can do  
something  
like:

original\_vector = Vector  
require ‘evilcode’ # or is it an include?  
Vector = original\_vector

---

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [December 11, 2009, 3:08pm UTC](https://www.ruby-forum.com/t/private-modules/180073/6 "2009-12-11T15:08:56Z")

</div>

David M. wrote:

> Hmm… I’m not sure that’s a good idea. Besides, the anonymous module  
> seems  
> like overkill. Maybe people will like your Vector class?

Well the whole point is to provide a better implementation for Vector,  
and at the same time spare users from having to prefix with “A” every  
reference to Vector.

The B module is actually going to be used by many classes under A, so I  
can’t just put it inside Vector.

---

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [December 11, 2009, 3:06pm UTC](https://www.ruby-forum.com/t/private-modules/180073/7 "2009-12-11T15:06:46Z")

</div>

Thomas S. wrote:

> Otherwise, probably nothing to worry about. You can’t clobber a  
> constant by using include if it already exists.
> 
> > > module A  
> > > module B  
> > > def self.b; “B”; end  
> > > def self.q; “Q”; end  
> > > end  
> > > end  
> > > =\> nil
> > 
> > > module B  
> > > def self.b; “B!”; end  
> > > end  
> > > =\> nil
> > 
> > > B.b  
> > > =\> “B!”
> > 
> > > include A  
> > > =\> Object
> > 
> > > B.b  
> > > =\> “B!”
> > 
> > > B.q  
> > > NoMethodError: undefined method `q’ for B:Module

That’s good to know. It just feel a little messy having all the  
internals exposed =b

---

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [December 11, 2009, 7:51pm UTC](https://www.ruby-forum.com/t/private-modules/180073/8 "2009-12-11T19:51:54Z")

</div>

On Dec 11, 9:09 am, Matt B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> can’t just put it inside Vector.  
> If B is a support module only used by A, then you might use an extra  
> submodule, you could even name it the same as the first:

module A

```
class Vector
   ...
   A::B::c_library_func(p)
   ...
end

module A

  module B
    ...
  end

end

```

end
