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§
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