166

Is there anything more idiomatic than the following?

foo.class == String

6 Answers 6

261

I think you are looking for instance_of?. is_a? and kind_of? will return true for instances from derived classes.

class X < String
end

foo = X.new

foo.is_a? String         # true
foo.kind_of? String      # true
foo.instance_of? String  # false
foo.instance_of? X       # true
Sign up to request clarification or add additional context in comments.

3 Comments

Without knowing the question's intent, I'd say for most real-world programming situations, is_a? is actually the more appropriate idiom to use (and often a duck-typing check like Andrew Grimm mentions is even better). A strict class comparison is usually a code smell. en.wikipedia.org/wiki/Liskov_substitution_principle
Quick aside: if you use this in conditional logic you need to use parentheses; eg, if foo.is_a?(String) && ...
As expected, this approach will work not only with String, but also with Integer and Float. Does it also work for Decimal? (the sublime text interpreter highlights the syntax differently for Decimal which makes me suspicious)
35

You can do:

foo.instance_of?(String)

And the more general:

foo.kind_of?(String)

1 Comment

davidchambers and steenslag noted that kind_of? is a synonym for is_a?. Unfortunately, including these comments as discussed for example here was rejected.
34

A more duck-typing approach would be to say

foo.respond_to?(:to_str)

to_str indicates that an object's class may not be an actual descendant of the String, but the object itself is very much string-like (stringy?).

4 Comments

Cool. In this case I happen to know that foo will either be true, false, or a vanilla string, but it's good to learn more general solutions.
combine this with a to_s call after checking if the object responds_to it, and you got yourself a string!
@seanmakesgames Did you mean to_str, or to_s? The two are slightly different.
8
foo.instance_of? String

or

foo.kind_of? String 

if you you only care if it is derrived from String somewhere up its inheritance chain

1 Comment

Isn't that a duplicate of this answer?
5

In addition to the other answers, Class defines the method === to test whether an object is an instance of that class.

  • o.class class of o.
  • o.instance_of? c determines whether o.class == c
  • c === o for a class or module, determine if o.is_a? c (String === "s" returns true)
  • o.is_a? c Is o an instance of c or any of it's subclasses?
  • o.kind_of? c synonym for is_a?

1 Comment

Note the subtle difference between == and ===.
-1

I think a better way is to create some predicate methods. This will also save your "Single Point of Control".

class Object
 def is_string?
   false
 end
end

class String
 def is_string?
   true
 end
end

print "test".is_string? #=> true
print 1.is_string?      #=> false

The more duck typing way ;)

2 Comments

what's wrong with "string".is_a?(String). It seems like you're reinventing the wheel. There's also class, instance_of, kind_of, etc... Bad idea to monkey patch the Object class, not to mention it's needless.
I totally agree with you :) If your focus is only on primitve types and you know that your project requirements related to primitive types will never change (ok its usually the case ;) ) youre fine. But in a case where requirements change its better to have a "Single Point of Control". For example in your project environment you have a lot of pre checks (1000 and up). pre_check("test".is_string?) Now your project requirement will change and every String with three characters or more is no longer defined as String (i know its unusual ;)) Now you can change your own method easily.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.