3

在 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

4 回答 4

8

尝试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上的方法列出对象的所有祖先class。比如1.class.ancestors给你[Fixnum, Integer, Precision, Numeric, Comparable, Object, PP::ObjectMixin, Kernel]

于 2010-11-26T12:11:40.427 回答
3

只需使用.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
于 2010-11-26T12:00:28.050 回答
0
o.class.ancestors

使用该列表,我们可以实现 has_super_class? 像这样(作为单音方法):

def o.has_super_class?(sc)
  self.class.ancestors.include? sc
end
于 2010-11-26T11:53:50.693 回答
0

激进的方式:

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"
于 2014-10-03T18:21:05.657 回答