I've since run into a use case in a large Rails app with complex namespacing. A simplified example:
# app/models/invoice/dependents/item.rb
class Invoice
module Dependents
class Item
# Define invoice item
end
end
end
Here Invoice
is a class of its own, but is also a good namespace for its dependent items. We can't say module Invoice
because that constant is already defined as a class, but we can still use it as a namespace.
Giant Caveat
If you use a class as a namespace, and you're using Rails, ensure you do not accidentally declare that class elsewhere. Autoloading will ruin your day. For instance:
# app/helpers/invoice/dependents/items_helper.rb
class Invoice # This line will cause you grief
module Dependents
module ItemsHelper
# view helper methods
end
end
end
The fact that class Invoice
is stated in this file creates a load order dependency; if this file's class Invoice
line is executed before your intended class definition, your intended class definition may not work properly. In this example, I can't declare that Invoice
sublcasses ActiveRecord::Base
if Invoice
has already been declared with no parent class.
You could require your "true" class definition file at the top of another file, but at least in a Rails autoloading scenario, you'll have less wrangling to do if you do this instead:
# app/helpers/invoice/dependents/items_helper.rb
module Invoice:Dependents::ItemsHelper
# view helper methods
end
With this syntax, Rails will see the Invoice
constant and use autoload to look it up, finding it in your model file and defining it the way you intended.