Ruby is_a?模块内部定义的类返回true

myss37ts  于 2023-06-22  发布在  Ruby
关注(0)|答案(2)|浏览(125)

下面代码中的“puts A::B::C.is_a?Module”返回true,如果C是模块中的类,则应返回false。

module A
    module B
        class C
            puts A::B.is_a?Class
            puts A::B.is_a?Module
            
            puts A::B::C.is_a?Class
            puts A::B::C.is_a?Module 
        end
    end
end
false
true
true
true

我想写一个递归函数,它检查类或模块示例以执行操作。请查看下面的代码片段。

def recursive(rootModule)
                sampleList = []
                rootModule.constants.map do |c|
                    nextLayer = rootModule.const_get(c)

                    if nextLayer.is_a? Module
                        return recursive(nextLayer)
                    elsif nextLayer.is_a? Class
                        return sampleList << "alpha"
                    end
                end
            end
vsikbqxv

vsikbqxv1#

is_a?检查对象是否是类或其任何子类的示例。ClassModule的子类,所以is_a? Module对于classes * 和 * modules总是返回true。
由于Module是更通用的类型,所以不要问“这是一个模块吗?”,你应该问“这个模块不是一个类吗?“.

if nextLayer.is_a? Module
  # could be Module or Class
  if nextLayer.is_a? Class
    # code for handling Classes
  else
    # code for handling Modules
  end
else
  # not a Module (so also not a Class). not all constants are Modules!
end
polkgigr

polkgigr2#

如上所述,Object#is_a?检查对象是否是类或其任何子类的示例,而ClassModule的子类。因此,您可以使用Object#instance_of?方法,如果obj是给定类的示例,则返回true。

if nextLayer.instance_of? Class
  # process classes
elsif nextLayer.instance_of? Module
 # process modules
else
  # process other constants
end

实际上,下面的代码也可以工作

if nextLayer.is_a? Class
  # process classes
elsif nextLayer.is_a? Module
 # process modules
else
  # process other constants
end

相关问题