Forum: Ruby Newb question - object type tests?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Adam B. (Guest)
on 2006-05-12 03:32
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?
Duane J. (Guest)
on 2006-05-12 03:46
(Received via mailing list)
On May 11, 2006, at 5:32 PM, Adam B. 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.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 J.
(canadaduane)
Logan C. (Guest)
on 2006-05-12 03:46
(Received via mailing list)
On May 11, 2006, at 7:32 PM, Adam B. wrote:

> item.array?
>> false
>
> extending that, how do I test the type of a class that I made?
>
> --
> Posted via http://www.ruby-forum.com/.
>

item.is_a? Array or item.kind_of? Array
Mike S. (Guest)
on 2006-05-12 03:46
(Received via mailing list)
On 11-May-06, at 7:32 PM, Adam B. wrote:

> item.array?
>> false
>
> extending that, how do I test the type of a class that I made?

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

--

Mike S. <removed_email_address@domain.invalid>
http://www.stok.ca/~mike/

The "`Stok' disclaimers" apply.
Adam B. (Guest)
on 2006-05-12 03:48
Thanks for all the replies. I remembered item.class moments after I
posted this. :) Stoopid me.

-Adam
James B. (Guest)
on 2006-05-12 03:49
(Received via mailing list)
Adam B. wrote:
> 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 B.

"People want simple stories."
Daniel S. (Guest)
on 2006-05-12 14:15
(Received via mailing list)
Adam B. wrote:
>> 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
Eric H. (Guest)
on 2006-05-12 22:34
(Received via mailing list)
On May 12, 2006, at 3:14 AM, Daniel S. 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.  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.

--
Eric H. - removed_email_address@domain.invalid - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com
Daniel S. (Guest)
on 2006-05-12 23:51
(Received via mailing list)
Eric H. 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.


>   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
Daniel S. (Guest)
on 2006-05-13 01:41
(Received via mailing list)
Daniel S. wrote:
> Eric H. 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 H. (Guest)
on 2006-05-13 02:05
(Received via mailing list)
On May 12, 2006, at 12:48 PM, Daniel S. wrote:
>> 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.

>
> 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].

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

> "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].

--
Eric H. - removed_email_address@domain.invalid - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com
This topic is locked and can not be replied to.