On Wed, Feb 2, 2011 at 10:49 AM, Pavel Strnad <pavel.strnad / fel.cvut.cz>wrote:

> Hi,
> I do not understand how is following code working:
> irb(main):001:0> module AAA
> irb(main):002:1> class BBB
> irb(main):003:2> end
> irb(main):004:1> end
> => nil
> irb(main):005:0> BBB::BBB
> NameError: uninitialized constant BBB
>        from (irb):5
>        from /usr/local/bin/irb:12:in `<main>'
> irb(main):006:0> AAA::BBB::BBB
> NameError: uninitialized constant AAA::BBB::BBB
>        from (irb):6
>        from /usr/local/bin/irb:12:in `<main>'
> irb(main):007:0> include AAA
> => Object
> irb(main):008:0> BBB::BBB
> => AAA::BBB
> irb(main):009:0> BBB::BBB::BBB
> => AAA::BBB
> irb(main):010:0> BBB::BBB::BBB::BBB
> => AAA::BBB
> irb(main):011:0> AAA::BBB::BBB::BBB
> => AAA::BBB
>
> I thought that last four lines will not work, but they do. How is it
> possible?
> Thank you.
> Pavel Strnad
>
>
The short answer is:

module A
  class B
  end
end
Object.ancestors # => [Object, Kernel, BasicObject]
include A
Object.ancestors # => [Object, A, Kernel, BasicObject]




What you should do to fix this is use extend rather than include:

module A
  class B
  end
end

extend A
begin
  B           # => A::B
  Fixnum::B   # =>
rescue
  $!          # => #<NameError: uninitialized constant Fixnum::B>
end

include A
begin
  B           # => A::B
  Fixnum::B   # => A::B
rescue
  $!          # =>
end


I made a post about it a while back, though I was talking about this problem
with methods rather than classes
http://groups.google.com/group/ruby-talk-google/browse_thread/thread/e33422848e168c4e?fwc=2