代码之家  ›  专栏  ›  技术社区  ›  arrac

Ruby:我们如何识别对象o在类层次结构中是否有一个类C作为其祖先?

  •  3
  • arrac  · 技术社区  · 15 年前

    在Ruby中,是否可以使用任何方法来识别对象o在类层次结构中是否有一个类C作为其祖先?

    我在下面给出了一个使用假设方法的例子 has_super_class? 去完成它。在现实中我应该怎么做?

    o = Array.new
    o[0] = 0.5
    o[1] = 1
    o[2] = "This is good"
    o[3] = Hash.new
    
    o.each do |value|
      if (value.has_super_class? Numeric)
        puts "Number"
      elsif (value.has_super_class? String)
        puts "String"
      else
        puts "Useless"
      end
    end
    

    预期产量:

    Number
    Number
    String
    Useless
    
    4 回复  |  直到 15 年前
        1
  •  8
  •   fifigyuri    15 年前

    尝试 obj.kind_of?(Klassname) :

    1.kind_of?(Fixnum) => true
    1.kind_of?(Numeric) => true
    ....
    1.kind_of?(Kernel) => true
    

    这个 kind_of? 方法也有相同的选择 is_a? .

    如果只想检查对象是否是类的(直接)实例,请使用 obj.instance_of? :

    1.instance_of?(Fixnum) => true
    1.instance_of?(Numeric) => false
    ....
    1.instance_of?(Kernel) => false
    

    也可以通过调用 ancestors its上的方法 class . 例如 1.class.ancestors 给你 [Fixnum, Integer, Precision, Numeric, Comparable, Object, PP::ObjectMixin, Kernel] .

        2
  •  3
  •   Gareth    15 年前

    只是使用 .is_a?

    o = [0.5, 1, "This is good", {}]
    
    o.each do |value|
      if (value.is_a? Numeric)
        puts "Number"
      elsif (value.is_a? String)
        puts "String"
      else
        puts "Useless"
      end
    end
    
    # =>
    Number
    Number
    String
    Useless
    
        3
  •  0
  •   Victor Deryagin    15 年前
    o.class.ancestors
    

    使用这个列表,我们可以实现has_super_类吗?像这样(单音法):

    def o.has_super_class?(sc)
      self.class.ancestors.include? sc
    end
    
        4
  •  0
  •   magicgregz    11 年前

    放射方式:

    1.class.ancestors => [Fixnum, Integer, Numeric, Comparable, Object, Kernel, BasicObject]
    1.class <= Fixnum => true
    1.class <= Numeric => true
    1.class >= Numeric => false
    1.class <= Array => nil
    

    如果你想看中它,你可以这样做:

    is_a = Proc.new do |obj, ancestor|
      a = { 
        -1 => "#{ancestor.name} is an ancestor of #{obj}",
        0 => "#{obj} is a #{ancestor.name}",
        nil => "#{obj} is not a #{ancestor.name}",
      }
      a[obj.class<=>ancestor]
    end
    
    is_a.call(1, Numeric) => "Numeric is an ancestor of 1"
    is_a.call(1, Array) => "1 is not a Array"
    is_a.call(1, Fixnum) => "1 is a Fixnum"
    
    推荐文章