Toplevel modules and classes

How do I get all defined toplevel modules and classes?
I can do it for specific module/class like in sample below, but
can’t figure out how to do it in toplevel context:

module Foo
module A
end

  module B
  end

  module C
  end

end

p Foo.constants # [“A”, “B”, “C”]

···


Best regards,
Eugene [team Enticla] mailto:Eugene.Scripnik@itgrp.net

  How do I get all defined toplevel modules and classes?

Object.constants don't do what you want ?

Guy Decoux

ruby -e ‘Object.constants.each{|c| c = Object.const_get(c); p c if c.kind_of?(Module)}’

···

In message “toplevel modules and classes” on 03/01/04, Eugene Scripnik Eugene.Scripnik@itgrp.net writes:

How do I get all defined toplevel modules and classes?

Friday, January 3, 2003, 5:33:08 PM, you wrote:

How do I get all defined toplevel modules and classes?
Object.constants don’t do what you want ?
Well… it looks much better than my solution:

list =
ObjectSpace.each_object( Module ) { |c|
list << c.name.split( /::confused: )[0]
}
list = list.uniq.sort

How do I check if a string is a class/module constant and then convert
it to class/module object?

···


Best regards,
Eugene [team Enticla] mailto:Eugene.Scripnik@itgrp.net

Friday, January 3, 2003, 5:49:04 PM, you wrote:

···

In message “toplevel modules and classes” > on 03/01/04, Eugene Scripnik Eugene.Scripnik@itgrp.net writes:

How do I get all defined toplevel modules and classes?

ruby -e ‘Object.constants.each{|c| c = Object.const_get(c); p c if c.kind_of?(Module)}’
Oops, didn’t see this message. Please ignore my previous one.
Thanks matz, thanks Guy.


Best regards,
Eugene [team Enticla] mailto:Eugene.Scripnik@itgrp.net

Friday, January 3, 2003, 5:49:04 PM, you wrote:

···

In message “toplevel modules and classes” > on 03/01/04, Eugene Scripnik Eugene.Scripnik@itgrp.net writes:

How do I get all defined toplevel modules and classes?

ruby -e ‘Object.constants.each{|c| c = Object.const_get(c); p c if c.kind_of?(Module)}’
OK, another question. Module#constants return constants accessible
in this module. But Class#constants produces the same output as
Object.constants (Class itself is an Object, right?). How do I get all
modules and classes defined in this particular class?


Best regards,
Eugene [team Enticla] mailto:Eugene.Scripnik@itgrp.net

OK, another question. Module#constants return constants accessible
in this module. But Class#constants produces the same output as
Object.constants (Class itself is an Object, right?). How do I get all

no, no you don't have the same output

pigeon% ruby -e 'class A; B = C = 12; end; p (A.constants - Object.constants)'
["B", "C"]
pigeon%

modules and classes defined in this particular class?

but you can't use this directly, because of this problem

pigeon% ruby -e 'class A; B = A = 12; end; p (A.constants - Object.constants)'
["B"]
pigeon%

something like this (it's strange for me to put classes in another class,
why do you want to do this ?)

pigeon% cat b.rb
#!/usr/bin/ruby
class A
   class A; end
   class B; end
end
A.constants.each do |kl|
   a = A.const_get(kl)
   b = Object.const_defined?(kl) && Object.const_get(kl)
   puts a if a != b && a.kind_of?(Module)
end
pigeon%

pigeon% b.rb
pigeon%

you must adapt it, if it's not a toplevel class

Guy Decoux

···

A::A
A::B

Friday, January 3, 2003, 7:23:55 PM, you wrote:

OK, another question. Module#constants return constants accessible
in this module. But Class#constants produces the same output as
Object.constants (Class itself is an Object, right?). How do I get all

no, no you don’t have the same output
Oh, sorry. I’ve tested on some standard classes and they actually
don’t have constants inside.

modules and classes defined in this particular class?
but you can’t use this directly, because of this problem

pigeon% ruby -e ‘class A; B = A = 12; end; p (A.constants - Object.constants)’
[“B”]
pigeon%
Class#constants == self_constants + Object.constants

something like this (it’s strange for me to put classes in another class,
why do you want to do this ?)
Well, I just wanted to build classes/modules tree of my application.
This structure is so complicated. And I wanted to do it in generalized
way and also was surprised when I put another class/module into class
and compiler found it OK.
So, both module and class accept defining modules and classes inside
them, but Class#constants and Module#constants behave in different
way. That was second surprise.

···

pigeon% cat b.rb
#!/usr/bin/ruby
class A
class A; end
class B; end
end
A.constants.each do |kl|
a = A.const_get(kl)
b = Object.const_defined?(kl) && Object.const_get(kl)
puts a if a != b && a.kind_of?(Module)
end
pigeon%

pigeon% b.rb
A::A
A::B
pigeon%

you must adapt it, if it’s not a toplevel class


Best regards,
Eugene [team Enticla] mailto:Eugene.Scripnik@itgrp.net

So, both module and class accept defining modules and classes inside
them, but Class#constants and Module#constants behave in different
way. That was second surprise.

When you call Class#constants (or Module#constants) ruby look in the
class and the super classes. a module don't have a superclass, this is why
ruby give the constant only in this module

Guy Decoux

Well, I just wanted to build classes/modules tree of my application.
This structure is so complicated. And I wanted to do it in generalized
way and also was surprised when I put another class/module into class
and compiler found it OK.
So, both module and class accept defining modules and classes inside
them, but Class#constants and Module#constants behave in different
way. That was second surprise.

There is instance_method and a singleton_method (class_method)
of the class “Module” called `constant’ .

···

“Eugene Scripnik” Eugene.Scripnik@itgrp.net wrote

class Module
p singleton_methods.include?(‘constants’) # true
end

class Module
p instance_methods.include?(‘constants’) # true
end

The singleton version calculates the current visible constants - this
depends
on the current binding - here is an old example illustrating the difference
between Object.constants (calling the instance version) and Module.constants
(Class.instance would work too) calling the singleton version.


def minus (bind)
puts eval(‘Module.constants - Object.constants’,bind).sort.join(', ')
end

A0 = 1
module A
B = ‘B’
class C
D = ‘D’
end
class E
F = ‘F’
end
end

minus binding # =>
module A
minus binding # => B, C, E
class C
minus binding # => B, C, D, E
end
class E
minus binding # => B, C, D, F
end
end

/Christoph

  a module don't have a superclass,

Well, except if you include another module in this module

Guy Decoux