From: Jeremy Evans Date: 2008-02-29T09:35:59+09:00 Subject: Re: constants defined in Kernel are also defined in Object? Joel VanderWerf wrote: > Jeremy Evans 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(c)) > 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 -- Posted via http://www.ruby-forum.com/.