March 11, 2008

Module.nesting and constant name resolution in Ruby

Filed under: ruby — Tags: — coderrr @ 10:31 am

Just finished the new O’Reilly Ruby book. It was mostly review but one thing I liked was their demonstration of constant name resolution. And I learned something new, Module.nesting!

Module.nesting returns the lexically enclosing classes/modules which are searched before Ruby walks up the class/module hierarchy to find the constant. Here’s an example of how Module.nesting doesn’t care about class hierarchy or namespaces, only lexical scope.

class A; end
class B; end
class C; end
class C::D; end
module E; end

class X < A; end
class Y < B; end
class Z < C; end

class ::X
  class ::Y
    class ::Z
      class ::C::D
        module ::M
          include E

          p Module.nesting

# => [M, C::D, Z, Y, X]

As you can see, the superclasses of X,Y,Z (A,B,C) are not present. The namespace of class D (C::) is not present either. Neither is the module E, which is included in M. Only the lexical nesting is returned.

The book has a good example which covers the entire lookup chain. Taken from The Ruby Programming Language:

module Kernel
  # Constants defined in Kernel
  A = B = C = D = E = F = "defined in kernel"

# Top-level or "global" constants defined in Object
A = B = C = D = E = "defined at toplevel"

class Super
  # Constants defined in a superclass
  A = B = C = D = "defined in superclass"

module Included
  # Constants defined in an included module
  A = B = C = "defined in included module"

module Enclosing
  # Constants defined in an enclosing module
  A = B = "defined in enclosing module"

  class Local < Super
    include Included

    # Locally defined constant
    A = "defined locally"

    # The list of modules searched, in the order searched
    # [Enclosing::Local, Enclosing, Included, Super, Object, Kernel]
    search = (Module.nesting + self.ancestors + Object.ancestors).uniq
    puts A  # Prints "defined locally"
    puts B  # Prints "defined in enclosing module"
    puts C  # Prints "defined in included module"
    puts D  # Prints "defined in superclass"
    puts E  # Prints "defined at toplevel"
    puts F  # Prints "defined in kernel"


  1. nice work, man

    Comment by Walterae — March 24, 2008 @ 8:45 am

  2. […] resolve the constant X from the same location we find it in the lexically enclosing module M. See this post for more info on constant […]

    Pingback by Overloading the parenthesis operator in Ruby « coderrr — November 30, 2008 @ 5:32 pm

  3. […] we are in the lexical scope of class A, as we can see by the module nesting. (For more info on module nesting see this […]

    Pingback by Fixing constant lookup in DSLs in Ruby 1.9 « coderrr — June 2, 2009 @ 8:16 pm

  4. […] — coderrr @ 11:37 pm Wanting to see if it would be possible to somehow dynamically modify Module.nesting I hacked around looking for ways to do this for a long time in 1.8 to no avail. But it seems that […]

    Pingback by Dynamically adding a constant nesting in Ruby 1.9 « coderrr — June 2, 2009 @ 8:19 pm

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Silver is the New Black Theme. Blog at


Get every new post delivered to your Inbox.

Join 29 other followers

%d bloggers like this: