我想制作一个标准化大量API的ruby gem
。
与连接到每个API相关联的逻辑需要抽象为.rb
个文件。要加载每个API的逻辑,我循环遍历文件夹的文件:
# Require individual API logic
Dir[File.dirname(__FILE__) + "/standard/apis/*.rb"].each do |file|
require file
end
每个API都是StandardAPI
的常量,因此我可以在每个API上迭代一些代码:
StandardAPI.constants.each do |constant|
# Standardize this stuff
end
但是,我也有VERSION
常数。它很好地循环我的API逻辑类,但是当我到达VERSION
时,我遇到了:
:VERSION is not a class/module (TypeError)
如何循环遍历每个API而忽略不是我所需类的常量?
答案 0 :(得分:3)
您似乎应该可以使用is_a?
class Test
end
Test.is_a?(Class)
=> true
VERSION = 42
VERSION.is_a?(Class)
=> false
答案 1 :(得分:3)
由于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]
答案 2 :(得分: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