const_defined? and inheritance

K

Kevin Howe

It seems that const_defined? doesnt search it's superclass:

class A
FOO = 'BAR'
end

class B < A; end

puts A.const_get:)FOO) # => 'BAR'
puts A.const_defined?:)FOO) # => true
puts B.const_get:)FOO) # => 'BAR'
puts B.const_defined?:)FOO) # => false

I had expected B.const_defined?:)FOO) to be true. Seems strange that
const_get does the lookup while const_defined? doesn't. Is there a reason
for this behaviour?

The following takes care of it:

class A
def self.const_defined?(symbol) super ||
superclass.const_defined?(symbol) end
end

But would like to know why this is.

Regards,
Kevin
 
D

David A. Black

Hi --

It seems that const_defined? doesnt search it's superclass:

class A
FOO = 'BAR'
end

class B < A; end

puts A.const_get:)FOO) # => 'BAR'
puts A.const_defined?:)FOO) # => true
puts B.const_get:)FOO) # => 'BAR'
puts B.const_defined?:)FOO) # => false

I had expected B.const_defined?:)FOO) to be true. Seems strange that
const_get does the lookup while const_defined? doesn't. Is there a reason
for this behaviour?

The following takes care of it:

class A
def self.const_defined?(symbol) super ||
superclass.const_defined?(symbol) end
end

But would like to know why this is.

I think they're just two different operations. The constants a module
can see ("get") is a superset of the constants it's defined.


David
 
K

Kevin Howe

class A
I think they're just two different operations. The constants a module
can see ("get") is a superset of the constants it's defined.

If that were the case then B.const_get:)FOO) would raise an error since B
does not define FOO. Instead it inherits it from A, and returns the
inherited value of "BAR". But you are probably right in the sense that
const_defined? shows only those explicitly set in that particular class.
I'll just use constants.include?('FOO') instead.

Regards,
Kevin
 
D

David A. Black

Hi --

If that were the case then B.const_get:)FOO) would raise an error since B
does not define FOO. Instead it inherits it from A, and returns the
inherited value of "BAR". But you are probably right in the sense that
const_defined? shows only those explicitly set in that particular class.

Yes, that's what I meant (and thought I'd said :) B can see A's FOO,
but B has not defined a FOO. "defined?", on that construction, means
"defined_by_the_receiver?", rather than
"defined_somewhere_and_visible_to_the_receiver?"
I'll just use constants.include?('FOO') instead.

To put a positive spin on it: note that Ruby gives you a way of
looking up constants on pretty much any of the possible criteria you'd
want to.


David
 
J

Joel VanderWerf

An alternative:

p defined?(B::FOO) # ==> "constant"

But this will include more than just the constants defined by A and B:

p defined?(B::Object) # ==> "constant"
 

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,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top