C extensions and class constants nested within modules

Hi all,

This appears to be perfectly legal Ruby code:

module Foo
    class Bar
    end
    class Bar::Baz
    end
end

p Foo::Bar.new # ok
p Foo::Bar::Baz.new # ok

However, an equivalent C extension has problems:

void Init_foo(){
    VALUE mFoo = rb_define_module("Foo");
    VALUE cBar = rb_define_class_under(mFoo, "Bar", rb_cObject);
    VALUE cBarBaz = rb_define_class_under(mFoo, "Bar::Baz", rb_cObject);
}

p Foo::Bar.new # ok
p Foo::Bar::Baz.new # uninitialized constant Foo::Bar::Baz (NameError)

Why doesn't that work?

The only way I could get it to work was to declare "Baz" under "Bar". But is that really the same thing?

Regards,

Dan

PS - I may have asked this before, but I'm old, my mind is going and Google is failing me.

Why doesn't that work?

Because this is parse.y and eval.c which make work

   class Bar::Baz
   end

and not the call to rb_define_class()

With rb_define_class("Bar::Baz"), ruby has defined a class "Bar::Baz" and
not a class Baz under Bar (what it look with Foo::Bar::Baz)

The only way I could get it to work was to declare "Baz" under "Bar". But is
that really the same thing?

In your case probably.

Guy Decoux

ts wrote:

"D" == Daniel Berger <Daniel.Berger@qwest.com> writes:

> Why doesn't that work?

Because this is parse.y and eval.c which make work

   class Bar::Baz
   end

and not the call to rb_define_class()

With rb_define_class("Bar::Baz"), ruby has defined a class "Bar::Baz" and
not a class Baz under Bar (what it look with Foo::Bar::Baz)

> The only way I could get it to work was to declare "Baz" under "Bar". But is > that really the same thing?

In your case probably.

What's the difference between these two?

module Foo
    class Bar
    end
    class Bar::Baz
    end
end

module Foo
    class Bar
       class Baz
       end
    end
end

Is there any difference? What are the potential pitfalls, if any?

Thanks,

Dan

Daniel Berger <Daniel.Berger@qwest.com> writes:

"D" == Daniel Berger <Daniel.Berger@qwest.com> writes:

> Why doesn't that work?
Because this is parse.y and eval.c which make work
   class Bar::Baz
   end
and not the call to rb_define_class()
With rb_define_class("Bar::Baz"), ruby has defined a class
"Bar::Baz" and
not a class Baz under Bar (what it look with Foo::Bar::Baz)
> The only way I could get it to work was to declare "Baz" under
"Bar". But is D> that really the same thing?
In your case probably.

What's the difference between these two?

module Foo
    class Bar
    end
    class Bar::Baz
    end
end

module Foo
    class Bar
       class Baz
       end
    end
end

Is there any difference? What are the potential pitfalls, if any?

You could hit issues with constant lookup, but from a code point
of view they should be the same.

···

Dan

--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org

module Foo
   A = :Foo
   class Bar
     A = :Bar
   end
   class Bar::Baz
     A # => :Foo
   end
end

module Foo
   class Bar
      class Baz
        A # => :Bar
      end
   end
end

RUBY_VERSION # => "1.8.3"

···

On Wed, Nov 23, 2005 at 03:34:48AM +0900, Daniel Berger wrote:

What's the difference between these two?

--
Mauricio Fernandez