Newb question - object type tests?


#1

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?


#2

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)


#3

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


#4

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

-Adam


#5

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.


#6

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


#7

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


#8

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


#9

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.


#10

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


#11

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