Const_defined? and inheritance

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

Hi --

···

On Sun, 13 Feb 2005, Kevin Howe wrote:

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

--
David A. Black
dblack@wobblini.net

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

Hi --

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

Yes, that's what I meant (and thought I'd said :slight_smile: 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

···

On Sun, 13 Feb 2005, Kevin Howe wrote:

--
David A. Black
dblack@wobblini.net

Kevin Howe wrote:

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

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"