Recipe 9.5. Avoiding Naming Collisions with NamespacesProblemYou want to define a class or module whose name conflicts with an existing class or module, or you want to prevent someone else from coming along later and defining a class whose name conflicts with yours. SolutionA Ruby module can contain classes and other modules, which means you can use it as a namespace. Here's some code from a physics library that defines a class called String within the StringTheory module. The real name of this class is its fully-qualified name: StringTheory::String. It's a totally different class from Ruby's built-in String class.
DiscussionIf you've read Recipe 8.17, you've already seen You can qualify the name of any Ruby object this way: a variable, a class, or even another module. Ruby's standard library uses namespaces heavily as an organizing principle. An excellent example is REXML, the standard XML library. It defines a REXML namespace that includes lots of XML-related classes like REXML::Comment and REXML::Instruction. Naming those classes Comment and Instruction would be a disaster: they'd get overwritten by other librarys' Comment and Instruction classes. Since nothing about the genericsounding names relates them to the REXML library, you might look at someone else's code for a long time before realizing that the Comment objects have to do with XML. Namespaces can be nested: see for instance rexml's REXML::Parsers module, which contains classes like REXML::Parsers::StreamParser. Namespaces group similar classes in one place so you can find what you're looking for; nested namespaces do the same for namespaces. In Ruby, you should name your top-level module after your software project (SAX), or after the task it performs (XML::Parser). If you're writing Yet Another implementation of something that already exists, you should make sure your namespace includes your project name (XML::Parser::SAX). This is in contrast to Java's namespaces: they exist in its package structure, which follows a naming convention that includes a domain name, like org.xml.sax. All code within a module is implicitly qualified with the name of the module. This can cause problems for a module like StringTheory, if it needs to use Ruby's built-in String class for something. This should be fixed in Ruby 2.0, but you can also fix it by setting the built-in String class to a variable before defining your StringTheory::String class. Here's a version of the StringTheory module that can use Ruby's builtin String class:
See Also
|
Thursday, October 29, 2009
Recipe 9.5. Avoiding Naming Collisions with Namespaces
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment