Mike Blyth
Mike Blyth

Reputation: 4258

Ruby: Reopening a Class from within a Module

Why doesn't this work?

module XT
  puts Fixnum.class  # So we're sure to re-open the Fixnum class
  class Fixnum
    def hi
      puts "HI from module XT"
    end
  end
end

After requiring and loading the module, the hi method is still not added to Fixnum. It works if I remove the module wrapper.

Upvotes: 1

Views: 1452

Answers (2)

Jörg W Mittag
Jörg W Mittag

Reputation: 369584

As @Jeremy wrote, constants are namespaced by modules, and defining a class is really just assigning a class object to a constant. Basically,

class Fixnum; end

is (roughly) equivalent to

Fixnum = Class.new

(except for the fact that if Fixnum already exists, the former will reopen it, while the latter will overwrite it).

This means that if you do that inside of a module (or class, since class IS-A module), the constant Fixnum will be namespaced inside that module.

If you want to explicitly access a top-level constant, you can tell Ruby to start its lookup at the top-level in a very similar vein to how you tell Unix to start filesystem lookup at the top-level:

module XT
  class ::Fixnum; end
end

Upvotes: 6

Jeremy
Jeremy

Reputation: 22435

You are defining XT::Fixnum, not Fixnum.

Upvotes: 4

Related Questions