C extensions and class constants nested within modules


#1

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.


#2

“D” == Daniel B. removed_email_address@domain.invalid writes:

D> 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)

D> 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.

Guy Decoux


#3

ts wrote:

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)

D> 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?

Thanks,

Dan


#4

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

What’s the difference between these two?

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”


#5

Daniel B. removed_email_address@domain.invalid writes:

“Bar”. But is D> that really the same thing?

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.