Constant visibility

G

Gavin Sinclair

Folks,

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

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
 
R

Robert Klemme

Gavin Sinclair said:
Folks,

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

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)
2) 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
 
G

Gavin Sinclair

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
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
 
T

ts

G> To my mind, the way things work (scope-wise) should depend on the
G> 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
 
R

Robert Klemme

Gavin Sinclair said:
"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

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
 
G

Gavin Sinclair

G>> To my mind, the way things work (scope-wise) should depend on the
G>> 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%


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

Gavin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,968
Messages
2,570,154
Members
46,702
Latest member
LukasConde

Latest Threads

Top