我只学习了 Ruby 的深层部分几个月,所以如果这是一个有点愚蠢的问题,我深表歉意。我正在尝试递归迭代一个可能包含嵌套数组的数组,因此我需要检查当前元素的类型。我有以下代码作为一个小测试:
arr = [ 1..2, [3..4, [5..6]], [7..8, [9..10]] ]
arr.each do |node|
p node.class
p node.instance_of? Array
end
当我运行它时,我得到以下输出:
Range
false
Array
false
Array
false
我希望最后两个返回 True,因为我有一个包含 Range 和两个嵌套数组的数组。
更奇怪的是,如果我写以下内容:
node.class.name == "Array"
它应该返回 True。
这里发生了什么事?
红宝石版本: MRI 1.9.3-p194
注意:我最终意识到这是由于我使用模块命名我的代码以避免代码冲突的方式,就像这样,但也以一种顽皮的方式验证对象身份:
module MyProg
class MyClass
attr_reader :my_array
def initialize(size)
@my_array = Array.new(size)
end
end
end
MyProg::MyClass.new
这样做会隔离您的代码,但会导致从您的命名空间下开始解析所有类查找。这意味着在上面的示例中,my_array.class
实际上会解析为MyProg::Array
而不是全局 Array 类。
如果你像这样命名空间并且你仍然想使用这个方法,你可以通过在类之前使用双冒号全局标识符来强制 Ruby 从全局命名空间开始查找来解决它:
arr.is_a? ::Array
arr.is_a? ::String
然而,鉴于 Ruby 的 Duck Typing 能力(以及以后更好的代码维护),您应该按照下面彼得的建议测试对象的行为。因此,我将他的答案标记为正确,以便为学习者提供一些极好的帮助!