Selector Namespace

Description

Selector namespaces are a way to provide a distinction between identical method names in the same object. As modules can be used to provide a namespace for classes, selector namespaces provide a namespace for individual methods within that class.

Use Cases

Selector namespaces would have two main use cases. First, subclasses can use it to override an inherited method. The overridden method in question would make sense in its own context. However a programmer may still wish to access its parent's method of the same name, either to avoid confusion for the end user of the class in question, or to provide a way for end users to access either method in its appropriate context, or both.

Consider the following example with our theoretical notation:
class UString < String
   namespace :unicode

   # chars instead of bytes
   def size
      wstrlen(self)
   end
end

string = UString.new("Ελλάσ") # "Hellas (Greece)" 

p string.size          # 10
p string::unicode.size # 5

The second use case is as an alternative, safe way to monkeypatch a base Sapphire class instead of subclassing. For example, there was recently a conflict between Ruby and Rails with regards to the String#chars method. The Rails core team defined a String#chars method, only to have it defined in later versions of Ruby, but the implementations were incompatible.

Here's how that case would be handled with selector namespaces:
class String
   namespace :rails

   # array of chars
   def chars
      self.split('//')
   end
end

s = "hello" 
s.chars        # Ruby's base String#chars method
s::rails.chars # The Rails String#chars method

However, the above notation would quickly become impractical if we had to explicitly define the namespace for every call of every object that used our own custom method. Instead, a block form would be used, where everything within that block uses that particular namespace. Consider the following example:
namespace :rails do
   s = "hello" 
   s.chars # The chars method Rails has defined.
end

s.chars # Ruby's base String#chars method

Global Namespaces

Another idea would be to allow programmers to define a global namespace, ala C++, at the top of their script. All method calls made after that declaration would default to that namespace. For example:
using namespace 'rails'
s = "hello" 
s.chars # The Rails String#chars method

Modules

A namespace could be defined in a module and mixed in the same way a class defines a namespace. For example:
module MyModule
   namespace :mymodule

   def some_method
      puts "hello" 
   end
end

class MyClass
   include MyModule

   # Our own definition of some_method
   def some_method
      puts "world" 
   end
end

m = MyClass.new
m.some_method           # 'world'
m::mymodule.some_method # 'hello'

Conflicting Namespaces

If two modules were mixed in with the same namespace, the last module included wins, though a NamespaceWarning would be issued. For example:
module One
   namespace :number
   def hello
      puts "hello" 
   end
end

module Two
   namespace :number
   def hello
      puts "hi" 
   end
end

class MyClass
   include One
   include Two # raises a NamespaceWarning
end

m = MyClass.new
m::number.hello # 'hi'

Alternate Notation

I am leaning towards using the double colon notation strictly for namespaces. This would cause some breakage with Ruby code, but I find that the double colon notation is uncommon in the wild, and the duplicate notation has always annoyed me a little. By using re-using the double colon I not only disambiguate the two different kinds of notation, I can still keep the final notation Sapphire-ish.

However, I have not ruled out other notations. Another possibility is to use a single ":" to identify a namespace. This has the advantage of being a little shorter, and being familiar to Rake users. Two possibilities for this notation are:
s:unicode.size # Object:Namespace.method
unicode:s.size # Namespace:Object.method

The second is more Rake-ish.

Also available in: HTML TXT