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(p)
# ...
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.
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
···
On 12/10/2009 10:01 PM, Matt Bleh wrote:
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(p)
# ...
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.
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(p)
# ...
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?
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 Dec 10, 4:01 pm, Matt Bleh <phreakuenc...@gmail.com> wrote:
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.
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
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
···
On Thursday 10 December 2009 05:26:03 pm Matt Bleh 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?
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.
David Masover 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.
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
...
...
end
module A
module B
...
end
end
end
···
On Dec 11, 9:09 am, Matt Bleh <phreakuenc...@gmail.com> wrote:
A::c_library_func(p)