3

I want to make a ruby gem which standardizes a serious of APIs.

The logic associated with connecting to each API needs to be abstracted into .rb files. To load each of the API's logic, I'm looping through the files of a folder:

# Require individual API logic
Dir[File.dirname(__FILE__) + "/standard/apis/*.rb"].each do |file|
  require file
end

Each API is a constant of the StandardAPI, so I can to iterate some code over each API:

StandardAPI.constants.each do |constant|
  # Standardize this stuff
end

However, I have a VERSION constant too. It loops over my API logic classes just fine, but when I gets to VERSION, I run into:

:VERSION is not a class/module (TypeError)

How can I loop over each of the APIs ignoring constants that aren't my required classes?

4

3 回答 3

4

由于Module#constants返回一个符号数组,您必须首先使用 查找常量Module#const_get

Math.const_get(:PI)              #=> 3.141592653589793
StandardAPI.const_get(:VERSION)  #=> the value for StandardAPI::VERSION

然后你可以检查它是否是一个类:

Math.const_get(:PI).class                    #=> Float
Math.const_get(:PI).is_a? Class              #=> false
StandardAPI.const_get(:VERSION).is_a? Class  #=> false

过滤所有类:

StandardAPI.constants.select { |sym| StandardAPI.const_get(sym).is_a? Class }

另一种方法是收集子类,可能是Class#inherited

# standard_api/base.rb
module StandardAPI
  class Base
    @apis = []

    def self.inherited(subclass)
      @apis << subclass
    end

    def self.apis
      @apis
    end
  end
end

# standard_api/foo.rb
module StandardAPI
  class Foo < Base
  end
end

# standard_api/bar.rb
module StandardAPI
  class Bar < Base
  end
end

StandardAPI::Base.apis
#=> [StandardAPI::Foo, StandardAPI::Bar]
于 2013-09-10T08:30:36.203 回答
3

看来您应该可以使用is_a?

class Test
end

Test.is_a?(Class)
=> true

VERSION = 42

VERSION.is_a?(Class)
=> false
于 2013-09-10T08:09:41.790 回答
0

我想您可以捕获该异常并继续

StandardAPI.constants.each do |constant|
  begin
    # Standardize this stuff
    rescue TypeError
      next
  end
end

或如@jonas 提到的

StandardAPI.constants.each do |constant|
  if constant.is_a?(Class)
    # Standardize this stuff
  end
end
于 2013-09-10T08:09:32.007 回答