Namespaces in Rails

Hi everyone,

Can someone explain me why Rails does not take full advantage of namespaces? Rails itself is divided into modules but user classes are restricted to use only names that don't coincide with existing class names with is annoying. "Transaction", for example, is a reserved name. But I find it ugly to use a name other than "Transaction" for models that really ARE "Transactions".

Erik

Erik,

Simple answer is that Ruby does not use a package system like you will find in Java. This is just something you will have to live with and learn to work around. Even in Java a "package" is really nothing more that a way of "prefixing" class names. So you just need to devise your own way of prefixing your class name, or simply take note of the reserved names in Ruby and in Rails and avoid them.

As a long time Java user. I actually don't really miss the whole packaging system imposed by Java. Especially after they added the ridiculous restriction that you cannot access objects in the "default" namespace from a class that is in a package. Now that I've been developing in Cocoa and Ruby, I have come to appreciate the simplicity of having no "packaging" system. It is no longer practical to ignore the packaging system in Java, due my previously stated restriction.

I look at it this way, when defining a Java class that is in package "com.mycompany" named "Transaction" the "real" class name is com.mycompany.Transaction. I would personally prefer just understanding that "Transaction" is a database transaction class used by Rails and would instead name my class something more descriptive like "AccountTransaction"

In any case this issue could cause a "flame war" about the practicality of package systems. That is not my intention here. You're going to find people on both sides of that fence. I happened to have found a way to jump from the Java side of the fence, to the Objective-C (Cocoa) and Ruby side of the fence.

Cocoa addresses this problem by convention. If you are creating a framework that you expect to use in your other, then the classes contained in the framework get prefixed with two capital letters. This provides some protection from naming conflicts without adding the complexity of a full packaging system. Some examples would be NSArray, NSDictionary, CIImage, etc. Where NS stands for Next Step (the operating system from which this core framework was extracted), and CI stands for Core Image (another Cocoa framework).

Ruby uses a packaging system that uses modules instead of name prefices like Java. And Rails does put different sets of logic into separate modules. I just don't see why user code should not be in a module of its own. I don't want to prefix all my models, and prefixing just one seems inconsistent. Are there any "official" articles about this topic?

Erik

Erik,

While I agree the NS, CF, etc convention in Obj-C is the de-facto
solution for the non-namespaced nature of C in general, it is limited
since NS could just as easily be used by the the company Neanderthal
Solutions. This then forces longer abbreviation prefixes for
disambiguation. With Java, the nice thing about packages is that you
can refer to a class by its name if there is no ambiguity.
Otherwise, you provide the fully qualified name (including package).
Without namespacing, your class names are much longer. I think the
OP is really looking for a solution like modules. For instance, in
Ruby, it's perfectly legal to create a class named Bar inside the
module named Foo. It would be written as:

class Foo::Bar end

Then if we needed a Bar for drinking, we could create another class/ module:

class Drinking::Bar end

Each 'Bar' in that case is namespaced, providing context. This is
fundamentally similar to packaging in Java, with the added benefit
that modules can also act like Categories in Objective-C by adding in
methods.

The problem as the original poster brought up is that Rails doesn't
seem to really support this well for apps built with it (it certainly
uses it internally). There are certain benefits to the namespacing,
in addition to the distinct but identical class names it allows
providing context, you can then put classes inside subfolders
easily. ObjC doesn't really care where the files live in folder
structures, since you simply set the source folders in your compile
settings. However, Rails convention over configuration could be a
beautiful solution if it provided better support.

Viewing a rails app with lots of classes quickly becomes overwhelming
in Textmate, since there isn't any organization below the models
folder. XCode solves this with ObjC because you can create
artificial "groups" to organize your classes (both .h & .m) without
having to adjust compile settings, or use real folders with settings
changes.

Niels

Hi,

Solutions. This then forces longer abbreviation prefixes for disambiguation. With Java, the nice thing about packages is that you can refer to a class by its name if there is no ambiguity. Otherwise, you provide the fully qualified name (including package).

Yes, Ruby module namespaces work the same way.

The problem as the original poster brought up is that Rails doesn't seem to really support this well for apps built with it (it certainly uses it internally). There are certain benefits to the namespacing,

With respect, I would disagree. Rails 1.2 has full support for namespaces at the model-view-controller level. You can even move your whole app/ directory into a plugin. For migrations, you can have plugins with different migration streams using PluginAWeek's excellent plugin_migrations.

Viewing a rails app with lots of classes quickly becomes overwhelming in Textmate, since there isn't any organization below the models folder. XCode solves this with ObjC because you can create

Using Rails plugins, plus module namespaces, plus plugin_migrations lets you organise your site into distinct segments of functionality -- they call it "vertical application slices" I believe.

Have a look at Goldberg for example. It's a full web application framework with its own models, views, controllers, migrations and even routes in RAILS_ROOT/vendor/plugins/goldberg/. And all its classes are namespaced with "Goldberg::" so they don't conflict with any of your own classes.

http://goldberg.240gl.org

Regards, Dave Nelson