473

I'll use python as an example of what I'm looking for (you can think of it as pseudocode if you don't know Python):

>>> a = 1
>>> type(a)
<type 'int'>

I know in ruby I can do :

1.9.3p194 :002 > 1.class
 => Fixnum 

But is this the proper way to determine the type of the object?

Ethan Chen
  • 649
  • 1
  • 6
  • 17
Zippy Zeppoli
  • 5,847
  • 4
  • 18
  • 16
  • yes1 in ruby this is the way `.class`. – Arup Rakshit Apr 02 '13 at 16:50
  • @iAmRubuuu: No, it is not. `#class` returns the *class*, not the *type*. That's why it is *called* `#class`, after all. The OP asked about the type, not the class. Those two are completely different. – Jörg W Mittag Apr 03 '13 at 12:09
  • @DaveNewton: The OP asked about the type, not the class. Those two are completely different. `#class` returns the *class*, not the *type*. – Jörg W Mittag Apr 03 '13 at 12:09
  • 5
    @JörgWMittag Yet AFAICR that's what ` type` does in Python, although my memory is fuzzy. You'd need `isinstance` or check for responds. But simply saying "NOES!!!" isn't really helpful, now, is it? Instead consider being educational. – Dave Newton Apr 03 '13 at 12:43
  • 4
    @JörgWMittag While I'm sympathetic, OP provided code to mimic in Ruby. Unless you actually *educate* the OP saying noes isn't helpful, IMO. And even if you did, it would likely be informational only, since OP defined what s/he wanted thru code. – Dave Newton Apr 03 '13 at 13:12
  • @DaveNewton: In the question, the OP asks about the type, not the class. In the subject line, the OP asks about the type, not the class. In the code sample, the OP asks about the type, not the class. I don't really see how you can conclude from that that the OP asks about the class, not the type. – Jörg W Mittag Apr 04 '13 at 12:17
  • @JörgWMittag And you still refuse to educate the OP or provide a correct answer... Why? In any case, what do you believe Python's ` type` method returns? – Dave Newton Apr 04 '13 at 12:29
  • 6
    @JörgWMittag - in Ruby everything is an Object, so there's no primitive types as there are in Python (int, long, boolean etc.) As a result within Ruby, classes are type definitions. This is not limited to Ruby either, the word class and type are synonymous in several other languages, and more broadly in OOP theory. – ocodo Jan 03 '14 at 03:26
  • @Slomojo: in OO, the type of an object is the protocol it speaks. In Ruby, classed don't define protocols, they define *implementations* of protocols. Plus, they prescribe a particular data representation. But one of the basic tenets of OO is *representation independence*. Yes, in Java, C# and C++ classes are also types, but if you use classes as types you are not doing OO, you are doing ADT-oriented programming. (There's nothing wrong with that, but Ruby is OO, not ADT-oriented.) Only if you use interfaces as types are you doing OO. (That's no surprise, after all Java's interfaces are ) – Jörg W Mittag Jan 03 '14 at 04:34
  • (inspired by Objective-C's protocols which in turn are inspired by Smalltalk's idea of protocols.) This is all explained clearly in [William R. Cook](http://WCook.BlogSpot.Com/)'s paper [*On Understanding Data Abstraction, Revisited*](http://CS.UTexas.Edu/~wcook/Drafts/2009/essay.pdf), where, among other things, he explains the fundamental difference between classes and types. – Jörg W Mittag Jan 03 '14 at 04:37
  • 6
    Since we're really talking about Ruby here, Types and Classes are synonymous, there's no debate about this, all values are Objects. So for anyone simply talking about Ruby, Classes *are* Types. - ref: http://www.ruby-lang.org/en/about/ – ocodo Jan 03 '14 at 04:53
  • 2
    @JörgWMittag That essay is quite informative so far, and I'll read the rest of it when I get a chance. In particular, Cook seems to articulate quite well (and with much more background knowledge than I have) why it's incorrect to claim (as one of my professors did) that Python, Ruby, and other dynamically-typed languages "aren't *really* object-oriented" (what he probably meant, without realizing it, was that they weren't ADT-oriented). But Ruby isn't statically typed, so it doesn't have ADTs in the sense Cook is describing, so your objections on the basis of that distinction aren't helpful. – Kyle Strand Mar 25 '14 at 22:43
  • possible duplicate of [Check if Ruby object is a Boolean](http://stackoverflow.com/questions/3028243/check-if-ruby-object-is-a-boolean) – nawfal Jul 24 '14 at 01:56

6 Answers6

751

The proper way to determine the "type" of an object, which is a wobbly term in the Ruby world, is to call object.class.

Since classes can inherit from other classes, if you want to determine if an object is "of a particular type" you might call object.is_a?(ClassName) to see if object is of type ClassName or derived from it.

Normally type checking is not done in Ruby, but instead objects are assessed based on their ability to respond to particular methods, commonly called "Duck typing". In other words, if it responds to the methods you want, there's no reason to be particular about the type.

For example, object.is_a?(String) is too rigid since another class might implement methods that convert it into a string, or make it behave identically to how String behaves. object.respond_to?(:to_s) would be a better way to test that the object in question does what you want.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • 19
    -1. `#class` does *not* return the type of the object, it returns its *class*. The name should be a dead giveaway. Class and Type are two *completely* different concepts in OO. – Jörg W Mittag Apr 02 '13 at 22:57
  • 104
    @Jörg W Mittag: I disagree. "Class" and "processor speed" (to pick an example) are two completely different concepts, but "class" and "type" are closely related concepts. For instance, here's what [the Wikipedia article on Class](http://en.wikipedia.org/wiki/Class_%28computer_programming%29) says: "In object-oriented programming, a class is a construct that is used to define a distinct type." tadman was being helpful to the questioner. – Teemu Leisti Aug 27 '13 at 13:26
  • 1
    @TeemuLeisti: That information is just plain wrong. Classes define *Representations*, Protocols define *Types*. The defining characteristic of Object-Orientation is that a single type can have multiple representations, i.e. that a single protocol can be provided by multiple classes. For example, in Ruby, the `IO` *type* is implemented by both the `IO` *class* and the `StringIO` *class*. The `Enumerable` *type* has a single method `each`, whereas the `Enumerable` *class* (actually *mixin*) has every method *except* `each`. – Jörg W Mittag Aug 27 '13 at 14:22
  • 23
    @JörgWMittag In Ruby the closest thing to `typeof` from C, JavaScript and others is `class`. There's no formal protocol system in Ruby like there is in other languages, Objective-C being the closest Smalltalk relative with that. If you're defining "type" as "object which responds to a particular set of methods with acceptable results" then there's really no way to assert that. It's just too loose. Most of the time in Ruby when referring to an object's type, it's understood you're talking about the class. I did use the term type in quotation marks for that very reason. – tadman Aug 27 '13 at 14:36
  • 2
    @TeemuLeisti: This has been well understood since at least the 1970s. See for example *User-defined types and procedural data structures as complementary approaches to data abstraction* by J. C. Reynolds in New Advances in Algorithmic Languages, INRIA, 1975 or [*On Understanding Data Abstraction, Revisited* by William R.Cook](http://www.cs.utexas.edu/~wcook/Drafts/2009/essay.pdf) – Jörg W Mittag Aug 27 '13 at 14:40
  • 16
    @Jörg W Mittag: I continue to assert that "class" and "type" are certainly not completely different concepts in OO, as demonstrated by the quote. (Also: how do you declare a variable in Java? By giving *either* the *type* or the *class* of the variable, followed by its name: "`int i`" or "`Integer j`".) tadman answered the question in a way that seemed to satisfy both the questioner and the general audience, while clarifying the terminology Ruby uses. I have no interest in getting into academic hair-splitting over the finer points of object-oriented terminology, so please have the last word. – Teemu Leisti Aug 27 '13 at 14:56
  • 11
    @TeemuLeisti Most of the trouble here comes from the fact that *everything* in Ruby is an object, and so has a class, whereas in virtually every other language there's primitive *types* which are not objects and have no class, in contrast to objects which do. When there's no such thing as a pure type, and no way to formally define one, the meaning becomes especially hazy in the Ruby world. Matz is not strictly adhering to any particular school of thought here other than his own. – tadman Aug 27 '13 at 15:21
  • 3
    @JörgWMittag I read the essay you posted and the problem is that ruby has no types or (ADTs) as mentioned in the paper. Your statement that "Types" and "Classes" are completely different is wrong in this case because in Ruby everything is a class even what you would call types. Integers, Strings, Floats, etc. are all classes in Ruby. Which is why tadman is right. The CLOSEST you can get to type checking is using the class as a reference. In Javascript, C, C++, etc. your statement would have been 100% accurate and valid because those languages do have both "Classes" and "ADTs". – Alexander Luna Apr 14 '18 at 17:02
  • When contrasting the name of a type to any object implementing the type, imo the obj.instance_of?(name) example - such as provided below - might serve to address the question succinctly? – Sean Champ Nov 04 '21 at 16:33
  • The use of the term 'wobbly' is confusing and unclear. I think i understand what you're trying to say (ambiguous?), but it muddles your answer. Unless there is an accepted interpretation I'm unaware of. – Aiden Cullo Jul 24 '23 at 15:54
  • @AidenCullo It's something that means "unstable, unpredictable, not dependable", and is common use, at least in British-flavoured English. – tadman Jul 25 '23 at 14:41
  • @tadman it's not in the dictionary with that definition. I think it is too much of slang for SO. I can barely understand what is meant, and i'm a native speaker. Think about non-native speakers, and english speakers not from britain. – Aiden Cullo Jul 25 '23 at 15:23
  • @AidenCullo You're welcome to take it up on the Stack Exchange language site but I'm leaving it as-is here, as it adds flavour. That it took ten years for someone to point this out is suggesting, at least to me, that it's fine. – tadman Jul 25 '23 at 15:25
107

you could also try: instance_of?

p 1.instance_of? Fixnum    #=> True
p "1".instance_of? String  #=> True
p [1,2].instance_of? Array #=> True
Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317
53

Oftentimes in Ruby, you don't actually care what the object's class is, per se, you just care that it responds to a certain method. This is known as Duck Typing and you'll see it in all sorts of Ruby codebases.

So in many (if not most) cases, its best to use Duck Typing using #respond_to?(method):

object.respond_to?(:to_i)
Stuart M
  • 11,458
  • 6
  • 45
  • 59
  • 1
    valid point. doesn't answer the question but hits the spirit of the question. – user566245 Sep 23 '15 at 19:31
  • 2
    @user566245 well it responds_to?(:the_question), but like you said it doesn't answer the question, just gives related information. Pretty sure answers need to answer the question. – R. Rincón Jun 13 '20 at 17:45
36

I would say "yes". Matz had said something like this in one of his talks, "Ruby objects have no types." Not all of it but the part that he is trying to get across to us. Why would anyone have said "Everything is an Object" then? To add he said "Data has Types not objects".

RubyConf 2016 - Opening Keynote by Yukihiro 'Matz' Matsumoto

But Ruby doesn't care as much about the type of object as the class. We use classes, not types. All data, then, has a class.

12345.class

'my string'.class

Classes may also have ancestors

Object.ancestors

They also have meta classes but I'll save you the details on that.

Once you know the class then you'll be able to lookup what methods you may use for it. That's where the "data type" is needed. If you really want to get into details the look up...

"The Ruby Object Model"

This is the term used for how Ruby handles objects. It's all internal so you don't really see much of this but it's nice to know. But that's another topic.

Yes! The class is the data type. Objects have classes and data has types. So if you know about data bases then you know there are only a finite set of types.

text blocks numbers

Rob Bednark
  • 25,981
  • 23
  • 80
  • 125
Douglas G. Allen
  • 2,203
  • 21
  • 20
4

variable_name.class

Here variable name is "a" a.class

3

every variable have a prop with name class. if you print it, it will tell you what type it is. so do like this:

puts a.class
shakib
  • 61
  • 1
  • 6