Joel VanderWerf wrote:
Jeremy E. wrote:
Class.const_defined?(:FOO)’
irb(main):004:0> class Foo
irb(main):010:0> Kernel.const_set(:FOO, 42) # sets FOO
=> 42
irb(main):011:0> Object.const_defined?(:FOO) # looks for FOO
=> true
irb(main):012:0> Class.const_defined?(:FOO) # looks for Class::FOO
=> false
irb(main):013:0> Class.const_set(:FOO, 42) # sets Class::FOO
=> 42
irb(main):014:0> Class.const_defined?(:FOO) # looks for Class::FOO
=> true
There still seems to be something unique in the relationship between
Kernel and Object. Can you replicate it?
I think that Kernel and Object are special in that their constants are
available in the top level namespace. Other than there isn’t much
difference between them and other classes in this case.
module MyKernel
FOO = 42
end
module Kernel
FOO = 42
end
class MyObject
include MyKernel
extend MyKernel
# what else do we have to do?
end
Alternatives to assigning to FOO above
MyKernel.const_set(:BAR, 42)
Kernel.const_set(:BAR, 42)
p MyObject.const_defined?(:FOO) # ==> false
p MyObject.const_defined?(:BAR) # ==> false
p Object.const_defined?(:FOO) # ==> true
p Object.const_defined?(:BAR) # ==> true
Can you make the outputs be true in the MyObject case?
irb(main):001:0> module MyKernel
irb(main):002:1> def self.included(klass)
irb(main):003:2> klass.const_set(:FOO, 42)
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0> class MyObject
irb(main):007:1> include MyKernel
irb(main):008:1> end
=> MyObject
irb(main):009:0> MyObject.const_defined?(:FOO)
=> true
The following works for constants that are already defined only (which
is not how Object and Kernel behave):
class MyObject
MyKernel.constants.each do |c|
const_set(c, MyKernel.const_get©)
end
end
If I understand you correctly, you want all constants in MyKernel to be
available in MyObject directly, even if the constants are added to
MyKernel after after it is included in MyObject. If that is what you
want, you’ll probably have to use the MyKernel.included method to store
a list of classes that include MyKernel, and override const_set on
MyKernel to add the constants to those classes in addition to adding it
to itself.
Alternatively, if you want MyObject to have direct access to any
constants in any included modules, you could override const_get on
MyObject to check all included_modules if the constant isn’t found in
MyObject.
I’m not sure why you would want to do either of those things, though.
Jeremy