# Method Namespace

**URL:** <https://www.ruby-forum.com/t/method-namespace/78344>\
**Category:** Ruby\
**Created:** [December 5, 2006, 4:10am UTC](https://www.ruby-forum.com/t/method-namespace/78344 "2006-12-05T04:10:04Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [December 5, 2006, 4:10am UTC](https://www.ruby-forum.com/t/method-namespace/78344/1 "2006-12-05T04:10:04Z")

</div>

I have need for a general purpose simple namespace construction. Not  
selector namespaces, mind you, just a method namespace. I made the  
following attempt. So close! But it fails b/c if a method is already  
defined in the class and the namespace module being added also has a  
method of the same name they will clash. I worked around it by aliasing  
the method with a temporary name then realiasing it to the original  
name. This words EXCEPT when super is called in the method (see the  
test case a the bottom).

Anone have any better ways of implementing?

Thanks,  
T.

# namespace.rb

require ‘facet/functor’  
require ‘facet/module/basename’

class Module

```
# Define a simple namespace.
#
# class A
# attr_writer :x
# namespace :inside do
# def x; @x; end
# end
# end
#
# a = A.new
# a.x = 10
# a.inside.x #=> 10
# a.x # no method error

def namespace( mod, &blk )

  # If block is given then create a module, othewise
  # get the name of the module.
  if block_given?
    name = mod.to_s
    mod = Module.new(&blk)
  else
    name = mod.basename.downcase
    mod = mod.dup
  end

  # We have to work around name clashes.
  nameclashes = mod.instance_methods & instance_methods
  nameclashes.each do |n|
    alias_method "#{n}:namespace", n
  end

  # Include the module. This is neccessary, otherwise
  # Ruby won't let us bind the instance methods.
  include mod

  # Undefine the instance methods of the module.
  mod.instance_methods.each{ |m| undef_method m }

  # Redefine the methods that clashed.
  nameclashes.each do |n|
    alias_method n, "#{n}:namespace"
    undef_method "#{n}:namespace"
  end

  # Add a method for the namespace that delegates
  # via the Functor to the module instance methods.
  define_method(name) do
    Functor.new(mod) do |op, base, *args|
      base.instance_method(op).bind(self).call(*args)
    end
  end
end

```

end

# begin test

require ‘test/unit’

class TestNamespace1 \< Test::Unit::TestCase

```
module M
  def x; "x"; end
end

class C
  namespace M
end

def test_01
  c = C.new
  assert_equal('x', c.m.x)
end

def test_02
  c = C.new
  assert_raises(NoMethodError){ c.x }
end

```

end

class TestNamespace2 \< Test::Unit::TestCase

```
class B
  def x; 1; end
end

class C < B
  def x; super; end
  namespace :m do
    def x; "x"; end
  end
end

def test_01
  c = C.new
  assert_equal('x', c.m.x)
end

# THIS FAILS !!!
def test_02
  c = C.new
  assert_equal(1, c.x)
end

```

end

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [December 5, 2006, 10:08pm UTC](https://www.ruby-forum.com/t/method-namespace/78344/2 "2006-12-05T22:08:43Z")

</div>

Trans schrieb:

> I have need for a general purpose simple namespace construction.  
> …  
> This words EXCEPT when super is called in the method (see the  
> test case a the bottom).  
> …

Tom, could you try this version?

def namespace( mod, &blk )

```
 # If block is given then create a module, otherwise
 # get the name of the module.
 if block_given?
   name = mod.to_s
   mod = Module.new(&blk)
 else
   name = mod.basename.downcase
   mod = mod.dup
 end

 # Include the module. This is neccessary, otherwise
 # Ruby won't let us bind the instance methods.
 include mod

 # Save the instance methods of the module and
 # replace them with a "transparent" version.
 methods = {}
 mod.instance_methods(false).each do |m|
   methods[m.to_sym] = mod.instance_method(m)
   mod.instance_eval do
     define_method(m) do
       super
     end
   end
 end

 # Add a method for the namespace that delegates
 # via the Functor to the saved instance methods.
 define_method(name) do
   Functor.new(methods) do |op, mtab, *args|
     mtab[op].bind(self).call(*args)
   end
 end

```

end

Regards,  
Pit

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [December 6, 2006, 6:04am UTC](https://www.ruby-forum.com/t/method-namespace/78344/3 "2006-12-06T06:04:19Z")

</div>

Pit C. wrote:

> ```
> name = mod.basename.downcase
> mod.instance_methods(false).each do |m|
> define_method(name) do
> Functor.new(methods) do |op, mtab, *args|
> mtab[op].bind(self).call(*args)
> end
> end
> 
> ```
> 
> end

Bloody hek, that’s a clever solution. Works like a charm. Pit Captain,  
you never cease to amaze! I’m putting this in Facets to replace the  
weak SimpleDelegtor I had been using.

Thanks!  
T.
