How to extract the class names?

I have written a code as below :

module A
  module B
    class B2
      class B1Error < Exception ;end
      class B2_inner
        $a = Module.constants
      end
    end
  end
end

$a - Module.constants
# => [:B1Error, :B2_inner, :B2, :B]

But now I want only the class names.. How to do so? means I want only
the below:

[:B1Error, :B2_inner, :B2]

···

--
Posted via http://www.ruby-forum.com/.

Module.constants.select { |const| Module.const_get(const).is_a? Class }

Don't have ruby so this might contain typos.

John

···

On Tue, Aug 20, 2013 at 1:55 PM, Love U Ruby <lists@ruby-forum.com> wrote:

I have written a code as below :

module A
  module B
    class B2
      class B1Error < Exception ;end
      class B2_inner
        $a = Module.constants
      end
    end
  end
end

$a - Module.constants
# => [:B1Error, :B2_inner, :B2, :B]

But now I want only the class names.. How to do so? means I want only
the below:

[:B1Error, :B2_inner, :B2]

--
Posted via http://www.ruby-forum.com/\.

John W Higgins wrote in post #1119210:

Module.constants.select { |const| Module.const_get(const).is_a? Class }

Don't have ruby so this might contain typos.

I am getting error.. :frowning:

module A
  module B
    class B2
      class B1Error < Exception ;end
      class B2_inner
        $a = Module.constants
      end
    end
  end
end

($a - Module.constants).select { |const| Module.const_get(const).is_a?
Class }
# =>
# ~> -:12:in `const_get': uninitialized constant Module::B1Error
(NameError)
# ~> from -:12:in `block in <main>'
# ~> from -:12:in `select'
# ~> from -:12:in `<main>'

···

--
Posted via http://www.ruby-forum.com/\.

This would work

    module A
      module B
        class B2
          class B1Error < Exception ;end
          class B2_inner
          end
        end
      end
    end

    def nested_classes(root)
      [].tap do |klasses|
        root.constants(false).map do |name|
          if (value = root.const_get(name)).is_a?(Module)
            klasses << value if value.is_a?(Class)
            klasses.concat(nested_classes(value))
          end
        end
      end
    end

    p nested_classes(A)
    # => [A::b::B2, A::b::B2::B1Error, A::b::B2::B2_inner]

Note however that the nesting does not necessarily reflect nested
namespaces.

root.constants(false).map do |name|

That #map should be an #each, it works but it is unnecessary (comes from
editing a previous attempt).

···

On Tue, Aug 20, 2013 at 11:32 PM, Xavier Noria <fxn@hashref.com> wrote:

Xavier Noria wrote in post #1119213:

That #map should be an #each, it works but it is unnecessary (comes from
editing a previous attempt).

Thanks for your reply:

I did it as below:

module A
  module B
    class B2
      class B1Error < Exception ;$b= Module.nesting ; end
      class B2_inner
        $a = Module.nesting
      end
    end
  end
end

($a | $b)
# => [A::b::B2::B2_inner, A::b::B2, A::B, A, A::b::B2::B1Error]
($a | $b).map{|e| e.respond_to?(:superclass)}
# => [true, true, false, false, true]
($a | $b).select{|e| e.respond_to?(:superclass)}
# => [A::b::B2::B2_inner, A::b::B2, A::b::B2::B1Error]

Is my approach is acceptable ?

···

--
Posted via http://www.ruby-forum.com/\.