3

In Ruby, is it possible to identify whether an object o has a class C as its ancestor in the class hierarchy using any method?

I've given an example below where I use a hypothetical method has_super_class? to accomplish it. How should I do this in reality?

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

Expected Output:

Number
Number
String
Useless
arrac
  • 597
  • 1
  • 5
  • 15

4 Answers4

8

Try obj.kind_of?(Klassname):

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

The kind_of? method has also an identical alternative is_a?.

If you want to check only whether an object is (direct) instance of a class, use obj.instance_of?:

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

You can also list all ancestors of an object by calling the ancestors method on its class. For instance 1.class.ancestors gives you [Fixnum, Integer, Precision, Numeric, Comparable, Object, PP::ObjectMixin, Kernel].

fifigyuri
  • 5,771
  • 8
  • 30
  • 50
3

Just use .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
Gareth
  • 133,157
  • 36
  • 148
  • 157
0

The rad way:

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

If you want to be fancy with it, you could do something like this:

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"
magicgregz
  • 7,471
  • 3
  • 35
  • 27
0
o.class.ancestors

using that list, we can implement has_super_class? like this (as singletone method):

def o.has_super_class?(sc)
  self.class.ancestors.include? sc
end
Victor Deryagin
  • 11,895
  • 1
  • 29
  • 38