26 December 2007

Ruby's require is lacking

I wrote a Ruby gem recently and named the gem 'publication_search'. It contained a single module called 'Publication' which, in turn, contained a class hierarchy. One such class was named 'Search'.

To use this gem, once it is installed, one could type within a Ruby program or the irb:
gem 'publication_search'
require 'Publication'
p = Publication::Search.new()
The problem is that in Ruby on Rails, one may decide to define a model (a class) called Publication. If you then try to use my publication_search gem you'll get all sorts of errors. The issue is that because of the way that classes and modules are stored internally by the Ruby interpreter you cannot have a module and a class with the same name. (See this blog entry for the details.)

The solution in this particular case is to rename the gem's module to something that is non-conflicting such as 'PublicationSearch'. But that's short-sighted because what if a Rails developer now wants to have a model named...you guessed it...PublicationSearch? The problem would be back.

It's not reasonable to rename the gem's module since the gem could be used widely in many different applications but the Rails app. only exists in one place even if it is distributed widely. It's also not reasonable to ask the Rails developer to rename his model so as not to conflict with the gem's module name.

Coming from the Python world, this kind of module namespace clash is a non-starter because you would simply write something like:
import publication_search.Publication as PubSearch
p = PubSearch.Search()
and this aliases the entire module as PubSearch. (You could alias it with whatever name you wanted -- I chose PubSearch.) From my research there does not appear to be anything analagous in Ruby. (If I am wrong, PLEASE let me know.)

No comments:

Post a Comment