Newb question - object type tests?

Hello all,

I feel like I definitely should know this, but how do you test the type
of an object? For example:

item = ["hello"]
item.array?

true

item = "hello"
item.array?

false

extending that, how do I test the type of a class that I made?

···

--
Posted via http://www.ruby-forum.com/\.

Hello all,

I feel like I definitely should know this, but how do you test the type
of an object? For example:

item = ["hello"]
item.array?

true

item.is_a? Array
=> true
item.class
=> Array

item = "hello"
item.array?

false

item.is_a? Array
=> false
item.class
=> String

extending that, how do I test the type of a class that I made?

It's built in to all classes (that derive from the Object class, and all classes do).

Duane Johnson
(canadaduane)

···

On May 11, 2006, at 5:32 PM, Adam Bloom wrote:

item.is_a? Array or item.kind_of? Array

···

On May 11, 2006, at 7:32 PM, Adam Bloom wrote:

Hello all,

I feel like I definitely should know this, but how do you test the type
of an object? For example:

item = ["hello"]
item.array?

true

item = "hello"
item.array?

false

extending that, how do I test the type of a class that I made?

--
Posted via http://www.ruby-forum.com/\.

If you are really interested then:

ratdog:~ mike$ irb
irb(main):001:0> item = ['hello']
=> ["hello"]
irb(main):002:0> item.kind_of?(Array)
=> true
irb(main):003:0> item = 'hello'
=> "hello"
irb(main):004:0> item.kind_of?(Array)
=> false
irb(main):005:0>

may be interesting to you, and you can look at the class of an object using the class method:

irb(main):006:0> item.class
=> String

There are plenty of ways to use Ruby without testing an object's class, and some good reasons why you might rue caring too much about specific classes - look for duck typing in the group's archives.

There are also good reasons to sniff around if you are interested in whether things are behaving as expected though.

Hope this helps,

Mike

···

On 11-May-06, at 7:32 PM, Adam Bloom wrote:

Hello all,

I feel like I definitely should know this, but how do you test the type
of an object? For example:

item = ["hello"]
item.array?

true

item = "hello"
item.array?

false

extending that, how do I test the type of a class that I made?

--

Mike Stok <mike@stok.ca>
http://www.stok.ca/~mike/

The "`Stok' disclaimers" apply.

Adam Bloom wrote:

Hello all,

I feel like I definitely should know this, but how do you test the type of an object? For example:

item = ["hello"]
item.array?

true

item = "hello"
item.array?

false

extending that, how do I test the type of a class that I made?

class Foo
   # some code ..
end

f = Foo.new

f.is_a? Foo

···

--
James Britt

"People want simple stories."

Adam Bloom wrote:

Hello all,

I feel like I definitely should know this, but how do you test the type of an object? For example:

item = ["hello"]
item.array?

true

item = "hello"
item.array?

false

extending that, how do I test the type of a class that I made?

Others have already shown you how to test the *class* of an object (note that in Ruby, the class isn't the same as the type).

If you want to be more Rubyish, try this:

   item = ["hello"]
   item.respond_to? :to_ary => true
   item = "hello"
   item.respond_to? :to_str => true

So if you're writing a method that requires a string, just do this:

   def foo(bar)
     str = bar.to_str
     str.split(...
   end

That way, all classes that consider themselves strings need only define a #to_str method. If they actually do define the same methods as String, #to_str can just return `self'; otherwise it can return a string representation.

Cheers,
Daniel

Thanks for all the replies. I remembered item.class moments after I
posted this. :slight_smile: Stoopid me.

-Adam

···

--
Posted via http://www.ruby-forum.com/.

If you want to be more Rubyish, try this:

  item = ["hello"]
  item.respond_to? :to_ary => true
  item = "hello"
  item.respond_to? :to_str => true

What you really want is to_a and to_s, not to_ary and to_str.

The to_xxx methods are used to convert an object that is an XXX representation into an XXX object when there is no inheritance relationship. If you're defining these methods you're probably doing something wrong.

So if you're writing a method that requires a string, just do this:

  def foo(bar)
    str = bar.to_str
    str.split(...
  end

The Ruby way to write that is:

def foo(bar)
   bar.split(...)
end

Maybe even throw in a to_s.

That way, all classes that consider themselves strings need only define a #to_str method.

I've never written a class that considered itself a string. Had a string representation, yes, but not one that was a String.

If they actually do define the same methods as String, #to_str can just return `self'; otherwise it can return a string representation.

No. to_xxx needs to return as XXX object, not self, unless it is defined on the XXX class. For example String#to_str would return self.

···

On May 12, 2006, at 3:14 AM, Daniel Schierbeck wrote:

--
Eric Hodel - drbrain@segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

Eric Hodel wrote:

If you want to be more Rubyish, try this:

  item = ["hello"]
  item.respond_to? :to_ary => true
  item = "hello"
  item.respond_to? :to_str => true

What you really want is to_a and to_s, not to_ary and to_str.

The to_xxx methods are used to convert an object that is an XXX representation into an XXX object when there is no inheritance relationship.

No, the #to_x methods do that. Only objects that are "strings", but not necessarily instances of String, should define #to_str.

So if you're writing a method that requires a string, just do this:

  def foo(bar)
    str = bar.to_str
    str.split(...
  end

The Ruby way to write that is:

def foo(bar)
  bar.split(...)
end

Funny, that isn't the behavior of, say, this

   .each(&obj)

Here, `obj' is converted to a Proc behind the scenes, by calling #to_proc on `obj'. Alternatively, #each could just call #call on the object for each object in the array, but it doesn't; it first calls #to_proc.

Almost every single (all?) class in Ruby defines a #to_s method, so the return value of it does not necessarily match the object itself. Take Proc#to_s for example.

That way, all classes that consider themselves strings need only define a #to_str method.

I've never written a class that considered itself a string. Had a string representation, yes, but not one that was a String.

   class Name
     attr_accessor :first, :last

     def initialize(first, last)
       @first, @last = first, last
     end

     def to_str
       to_s
     end

     def to_s
       "#{first} #{last}"
     end
   end

This may not be the best example, but you get the idea. An Email class may be better, but that'd be more complex (regexes and such).

If they actually do define the same methods as String, #to_str can just return `self'; otherwise it can return a string representation.

No. to_xxx needs to return as XXX object, not self, unless it is defined on the XXX class. For example String#to_str would return self.

For it to work with native Ruby methods, yes. But no purist is going to check the class of the object returned anyway. If the object doesn't respond to a method defined by the class it way "converted" to, that's the fault of the maker of the object, not the receiver.

Cheers
Daniel

···

On May 12, 2006, at 3:14 AM, Daniel Schierbeck wrote:

Daniel Schierbeck wrote:

Eric Hodel wrote:

The to_xxx methods are used to convert an object that is an XXX representation into an XXX object when there is no inheritance relationship.

No, the #to_x methods do that. Only objects that are "strings", but not necessarily instances of String, should define #to_str.

Reading it over again, I see what you mean. Yes, there are representations of objects, and those are what you're interested in. If you're going to perform some actions on a string, you can accept any object that responds to #to_str.

Eric Hodel wrote:

If you want to be more Rubyish, try this:

  item = ["hello"]
  item.respond_to? :to_ary => true
  item = "hello"
  item.respond_to? :to_str => true

What you really want is to_a and to_s, not to_ary and to_str.
The to_xxx methods are used to convert an object that is an XXX representation into an XXX object when there is no inheritance relationship.

No, the #to_x methods do that. Only objects that are "strings", but not necessarily instances of String, should define #to_str.

You are confusing is-a with has-a and I used bad terminology.

Objects that define #to_xxx are XXX versions (duck type to XXX) while objects that define #to_x have X representations.

So if you're writing a method that requires a string, just do this:

  def foo(bar)
    str = bar.to_str
    str.split(...
  end

The Ruby way to write that is:
def foo(bar)
  bar.split(...)
end

Funny, that isn't the behavior of, say, this

  .each(&obj)

Here, `obj' is converted to a Proc behind the scenes, by calling #to_proc on `obj'. Alternatively, #each could just call #call on the object for each object in the array, but it doesn't; it first calls #to_proc.

The & operator performs proc conversion. This cannot be done inside #each because the method signature is wrong.

def each(&block); end # implicit block
def each(block); end # no implicit block

Almost every single (all?) class in Ruby defines a #to_s method, so the return value of it does not necessarily match the object itself. Take Proc#to_s for example.

has-a vs is-a.

See [ruby-talk:96552], the thread starting at [ruby-talk:96554] and [ruby-talk:96567].

That way, all classes that consider themselves strings need only define a #to_str method.

I've never written a class that considered itself a string. Had a string representation, yes, but not one that was a String.

  class Name
    attr_accessor :first, :last

    def initialize(first, last)
      @first, @last = first, last
    end

    def to_str
      to_s
    end

    def to_s
      "#{first} #{last}"
    end
  end

This may not be the best example, but you get the idea. An Email class may be better, but that'd be more complex (regexes and such).

Names don't duck-type to Strings. You don't sub! them, you don't iterate over them, you don't do anything else you do with a String. If your object doesn't duck-quack like an XXX you shouldn't be defining #to_xxx.

#to_ary has utility with various data structures including linked-lists.

If they actually do define the same methods as String, #to_str can just return `self'; otherwise it can return a string representation.

No. to_xxx needs to return as XXX object, not self, unless it is defined on the XXX class. For example String#to_str would return self.

For it to work with native Ruby methods, yes. But no purist is going to check the class of the object returned anyway. If the object doesn't respond to a method defined by the class it way "converted" to, that's the fault of the maker of the object, not the receiver.

No. That isn't what #to_xxx is for. Read [ruby-talk:96567].

···

On May 12, 2006, at 12:48 PM, Daniel Schierbeck wrote:

On May 12, 2006, at 3:14 AM, Daniel Schierbeck wrote:

--
Eric Hodel - drbrain@segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com