简体   繁体   中英

List all Ruby classes and methods

For a while now I've wanted a way to inspect all changes made to a given ruby environment when a particular model is loaded. Furthermore, the ability to compare and contrast the methods and classes available in separate versions of ruby, and different Ruby VMs.

I've created some code which uses meta-programming to generate such a list:

arr = []
arr << "Ruby version " + ::RUBY_VERSION
arr << ""
Module.constants.each do |const|
  if ::Module.const_defined? const
    #If for whatever reason const_get fails, then rescue.
    begin
      obj = Module.const_get(const)
      if obj
        if obj.is_a? Class
        # Class methods
        arr << (obj.singleton_methods).sort.map do |method_sym|
          obj.to_s + "::" + method_sym.to_s
        end

        # Instance methods
        arr << (obj.instance_methods - (obj.superclass ? obj.superclass.instance_methods : []) - Object.methods).sort.map do |method_sym|
          "#<" + obj.to_s + ">." + method_sym.to_s
        end
        elsif obj.is_a? Module
          arr << (obj.methods - Module.methods).sort.map do |method_sym|
            obj.to_s + "::" + method_sym.to_s
          end
        else
          # Methods
          arr << "::" + const.to_s
        end
      end
    rescue
    end
  end
end

File.new("D:\\methods_#{::RUBY_VERSION}.txt","w").write(arr.flatten.sort.join("\n"))

The criteria for the list is that it should list all non-inherited instance and class methods. Constants are indicated with :: prefix, Class methods are indicated as MyClass::someMethod and instance methods are indicated as follows: #<MyClass>.someMethod .

The script above works for the most part however, it misses out Object and BasicObject . IE in the lists created there are no lines prefixed with #<Object>. or Object:: . Am I missing something obvious?

I suggest you create a hash for each Ruby version and then save that hash or its contents to a file whose name indicates the Ruby version (eg, v_2-5-1.json or v_2-5-1.txt )

While I don't fully understand the question, you may find he method ObjectSpace::each_object helpful here. For example,

h = ObjectSpace.each_object(Class).with_object({}) do |c,h|
  h[c] = { cm: c.methods(false).sort, im: c.instance_methods(false).sort,
           con: c.constants.sort }
end

h.keys && [Object, BasicObject]
  # [Object, BasicObject]

As you see Object and BasicObject are two keys (classes) in this hash. Let's look at the value of one of the keys: Dir .

h[Dir]
  #=> {:cm=>[:[], :chdir, :children, :chroot, :delete, :each_child, :empty?,
  #          :entries, :exist?, :exists?, :foreach, :getwd, :glob, :home,
  #          :mkdir, :open, :pwd, :rmdir, :unlink],
  #    :im=>[:close, :each, :fileno, :inspect, :path, :pos, :pos=, :read,
  #          :rewind, :seek, :tell, :to_path],
  #    :con=>[]}

This is for

RUBY_VERSION
  #=> "2.5.1"

Comparing the contents of this hash with the doc for Dir for v2.5.1 we see that the results are correct for the class Dir .

Obtaining constants defined within a class C is problematic. C.constants , which I've used above includes inherited constants. Were I to write C.constants - C.superclass.constants (mindful that BasicObject.superclass #=> nil ) that would not report inherited constants the are redefined in C (and redefining an inherited constant does not produce a warning message).

Instead of just looking at classes you may wish to examine all modules ( ObjectSpace.each_object(Module) ) and add a key :is_class to the hash with value true or false ):

There may be other keys you may wish to add to the hash. :superclass and :included_modules (for classes ) are two that comes to mind; :nesting (for non-class modules) is another. See Module::nesting . I suspect that these observations just scratch the surface, that a meaningful comparison of two Ruby versions will be highly complex.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM