Constant visibility

Folks,

I know this sort of thing has been talked about before, but that’s not
going to stop me :slight_smile:

module M
X = 5
class C
def foo
puts "X = #{X}"
end
end
end

class M::C
def bar
puts "X = #{X}"
end
end

M::C.new.foo # X = 5
M::C.new.bar # NameError: uninitialized constant M::C::X

The problem is that when you use ‘class M::C’ to open a class, you
can’t access constants declared in M, whereas if you use ‘module M;
class C’, you can.

  1. Why is this?

  2. Is is an intentional behaviour of Ruby?

I feel fairly confident that the new constant resolution rules will
sort this out, but I’m wondering why it can’t be made to work now.

ruby 1.8.1 (2004-01-08) [i386-cygwin]

Gavin

“Gavin Sinclair” gsinclair@soyabean.com.au schrieb im Newsbeitrag
news:1631699911313.20040201160309@soyabean.com.au…

Folks,

I know this sort of thing has been talked about before, but that’s not
going to stop me :slight_smile:

module M
X = 5
class C
def foo
puts “X = #{X}”
end
end
end

class M::C
def bar
puts “X = #{X}”
end
end

M::C.new.foo # X = 5
M::C.new.bar # NameError: uninitialized constant M::C::X

The problem is that when you use ‘class M::C’ to open a class, you
can’t access constants declared in M, whereas if you use ‘module M;
class C’, you can.

  1. Why is this?

Because when doing “class M::C” you’re still in another scope while defining
class C. So you have to explicitely scope constants from module M. (see
below)

  1. Is is an intentional behaviour of Ruby?

I think so.

I feel fairly confident that the new constant resolution rules will
sort this out, but I’m wondering why it can’t be made to work now.

ruby 1.8.1 (2004-01-08) [i386-cygwin]

Gavin

irb(main):014:0> module M
irb(main):015:1> X = 5
irb(main):016:1> class C
irb(main):017:2> def foo
irb(main):018:3> puts “X = #{X}”
irb(main):019:3> end
irb(main):020:2> end
irb(main):021:1> end
=> nil
irb(main):022:0>
irb(main):023:0* class M::C
irb(main):024:1> def bar
irb(main):025:2> puts “X = #{M::X}”
irb(main):026:2> end
irb(main):027:1> end
=> nil
irb(main):028:0>
irb(main):029:0* M::C.new.foo
X = 5
=> nil
irb(main):030:0> M::C.new.bar
X = 5
=> nil
irb(main):031:0>

$ ruby --version
ruby 1.8.1 (2003-12-25) [i386-cygwin]

Regards

robert

The problem is that when you use ‘class M::C’ to open a class, you
can’t access constants declared in M, whereas if you use ‘module M;
class C’, you can.

  1. Why is this?

Because when doing “class M::C” you’re still in another scope while defining
class C. So you have to explicitely scope constants from module M. (see
below)

“Another scope”? Sounds convincing, but I don’t know what it means.
‘self’ is the same object in the following two examples:

module M
class C
p self.id
end
end

class M::C
p self.id
end

  1. Is is an intentional behaviour of Ruby?

I think so.

Can it be justified in terms of correctness, language design
principles, POLS, convenience, expedience, or anything else?

To my mind, the way things work (scope-wise) should depend on the
value of ‘self’ and little if not nothing else.

Cheers,
Gavin

···

On Sunday, February 1, 2004, 10:19:53 PM, Robert wrote:

To my mind, the way things work (scope-wise) should depend on the
value of 'self' and little if not nothing else.

well, another example to see that ruby sometimes use something else than
self

svg% ruby -e 'Array.instance_eval { p self; def a() puts "a"; end }; Array.a'
Array
a
svg%

svg% ruby -e 'Array.module_eval { p self; def a() puts "a"; end }; .a'
Array
a
svg%

Guy Decoux

“Gavin Sinclair” gsinclair@soyabean.com.au schrieb im Newsbeitrag
news:421724876381.20040201225914@soyabean.com.au…

The problem is that when you use ‘class M::C’ to open a class, you
can’t access constants declared in M, whereas if you use ‘module M;
class C’, you can.

  1. Why is this?

Because when doing “class M::C” you’re still in another scope while
defining
class C. So you have to explicitely scope constants from module M. (see
below)

“Another scope”? Sounds convincing, but I don’t know what it means.
‘self’ is the same object in the following two examples:

module M
class C
p self.id
end
end

class M::C
p self.id
end

It’s the other self, the one that is used for the const lookup I guess:

module M
p self.id

class C; end
end

p self.id
class M::C;end

  1. Is is an intentional behaviour of Ruby?

I think so.

Can it be justified in terms of correctness, language design
principles, POLS, convenience, expedience, or anything else?

To my mind, the way things work (scope-wise) should depend on the
value of ‘self’ and little if not nothing else.

see above. Just my 0.02 EUR

robert
···

On Sunday, February 1, 2004, 10:19:53 PM, Robert wrote:

Good point. Still the exception rather than the rule, I hope :slight_smile:

Gavin

···

On Sunday, February 1, 2004, 11:07:11 PM, ts wrote:

To my mind, the way things work (scope-wise) should depend on the
value of ‘self’ and little if not nothing else.

well, another example to see that ruby sometimes use something else than
self

svg% ruby -e ‘Array.instance_eval { p self; def a() puts “a”; end }; Array.a’
Array
a
svg%

svg% ruby -e ‘Array.module_eval { p self; def a() puts “a”; end }; .a’
Array
a
svg%