"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(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?

Thank you

···

--
Posted via http://www.ruby-forum.com/.

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.

Is there a guideline for these cases?

Thank you

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

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.

Matt

···

--
Posted via http://www.ruby-forum.com/.

Thomas Sawyer 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

···

--
Posted via http://www.ruby-forum.com/\.

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.

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.

···

--
Posted via http://www.ruby-forum.com/\.

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::b::c_library_func(p)