"private" modules

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

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

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

On Dec 10, 4:01 pm, Matt B. [email protected] 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

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

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.

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

On Dec 11, 9:09 am, Matt B. [email protected] 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