ruby picture

RCR 218: kind_of class'es

Submitted by neoneye (Thu Feb 19 21:02:18 UTC 2004)

Abstract

Let #kind_of? take multiple arguments.

Problem

Its not visible at first sight, when this method will raise. If the number of classes to check is 3 or more, then its even more difficult.

def push(choice)
  unless choice.kind_of?(Zero) or choice.kind_of?(One)
    raise ArgumentError, "got #{choice.class}"
  end
  @choices <&lt; choice
end

Proposal

Now its much easier to tell when this method raises an exception.

def push(choice)
  unless choice.kind_of?(Zero, One)
    raise ArgumentError, "got #{choice.class}"
  end
  @choices <&lt; choice
end

Analysis

For consistency it probably also necessary to do the same with instance_of?.

Implementation

class Object
  alias old_kind_of kind_of?
  def kind_of?( *classes )
    classes.each{|cl| return true if old_kind_of(cl) }
    false
  end
end

p 3.kind_of?(String) # false p 3.kind_of?(String, Fixnum) # true
ruby picture
Comments Current voting

Hi --

My only reservation about this is that it makes it easier to write code littered with classname tests, which has always been a bit undesireable because it tends to divert people from learning about Ruby types. I'd be perfectly happy for kind_of? to disappear. Then again, as long as it's here, I suppose having multiple arguments makes some sense. So I've voted neutral. -- David Black


You can achieve the above (testing .kind_of? or .is_a? for multiple classes) rather painlessly with:

  if (choice.class.ancestors & [Zero,One]).length>0

The performance probably isn't as good as it could be with a native implementation, but do you really find yourself needing to multiply-match the ancestor chain of an instance all that often?

-- RabYak/Phrogz/Gavin Kistner


My problem with this is that when I see:

  p 3.kind_of?(String, Fixnum)

I don't see an 'and' or an 'or', so I don't know whether this is testing to see if 3 is both a String and a Fixnum or whether it is either a String or a Fixnum. I'd much rather see this explicitly stated, especially since it's not that much harder to do so.

-- Paul Brannan

Why would you want to connect these choices with and? Since Ruby is single inheritance, just test for the class that is the child of the others. a hypothetical kind_of?(String && Object) is exactly the same as kind_of?(String) ;-)

Besides, the way it is proposed, it can be implemented as just a normal method, no exceptional behaviour.

@David Black: If you want kind_of? to disappear, how would you then test which kind of object your method got? -- Icekiss

Icekiss: I wouldn't. I rarely do so now(only once in a while deep inside something where I want it an initializer to be able to normalize, say, a string or a Something to a Something). See ruby-talk archives for (much :-) more about this.

Ok, just found out about the respond_to? and read about duck typing. I guess I will have to read more about this subject... --Icekiss


Strongly opposed 2
Opposed 8
Neutral 4
In favor 5
Strongly advocate 1
ruby picture
If you have registered at RCRchive, you may now sign in below. If you have not registered, you may sign up for a username and password. Registering enables you to submit new RCRs, and vote and leave comments on existing RCRs.
Your username:
Your password:

ruby picture

Powered by .