ChatGPT解决这个技术问题 Extra ChatGPT

Check whether a variable is a string in Ruby

Is there anything more idiomatic than the following?

foo.class == String

C
Candide

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

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)
A
Andrew Grimm

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?).


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.
M
Milo P

You can do:

foo.instance_of?(String)

And the more general:

foo.kind_of?(String)

What makes kind_of more general? They appear to be synonymous: is_a.
@Davidchambers you're right, 'kind_of?' is a synonym for 'is_a?'.
@davidchambers: You're right, I meant instance_of? instead of is_a?.
M
Matthew
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


s
steenslag

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

o.is_a? c Is o an instance of c or any of it's subclasses?

o.kind_of? c synonym for *is_a?*

c === o for a class or module, determine if *o.is_a? c* (String === "s" returns true)


s
schlegel11

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 ;)


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.