Looking for object.inherits?(Classname)

X

Xeno Campanoli

I'm looking for a way to make sure an object being passed is in some class
family, or to say it otherwise, inherits some specific class, but not
necessarily directly. In fact, it could be a great-great-grandparent class, and
that would be okay, and needs to be okay. Is there something where I can take
an object and go

unless object.inherits?(MyClass)
raise SyntaxError, "etc."
end


?????

Sorry, but could not find this in my pickaxe book.
 
D

David A. Black

Hi --

I'm looking for a way to make sure an object being passed is in some class
family, or to say it otherwise, inherits some specific class, but not
necessarily directly. In fact, it could be a great-great-grandparent class,
and that would be okay, and needs to be okay. Is there something where I can
take an object and go

unless object.inherits?(MyClass)
raise SyntaxError, "etc."
end


?????

Sorry, but could not find this in my pickaxe book.

object.is_a?(MyClass)

or

object.kind_of?(MyClass)

(same method, two different names).


David

--
David A. Black
Senior Developer, Cyrus Innovation Inc.
THE COMPLEAT RUBYIST, Ruby training with Black/Brown/McAnally!
January 22-23, Tampa, Florida
Info and registration at http://www.thecompleatrubyist.com
 
D

David A. Black

Xeno Campanoli wrote:

Looks like the method I use is "ancestors".

Whoops, that means I misunderstood. Sorry.


David

--
David A. Black
Senior Developer, Cyrus Innovation Inc.
THE COMPLEAT RUBYIST, Ruby training with Black/Brown/McAnally!
January 22-23, Tampa, Florida
Info and registration at http://www.thecompleatrubyist.com
 
R

Rob Biedenharn

Whoops, that means I misunderstood. Sorry.


David

--
David A. Black
Senior Developer, Cyrus Innovation Inc.
THE COMPLEAT RUBYIST, Ruby training with Black/Brown/McAnally!
January 22-23, Tampa, Florida
Info and registration at http://www.thecompleatrubyist.com


irb> string="string"
=> "string"
irb> string.class
=> String
irb> string.class.ancestors
=> [String, Enumerable, Comparable, Object, Kernel]
irb> string.is_a?(String)
=> true
irb> string.is_a?(Comparable)
=> true
irb> string.kind_of?(Kernel)
=> true

It depends on whether you have an instance of the class or the class
object itself.

Xeno said that he had an object. I think David understood perfectly
and his answer is exactly what you want.

-Rob

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)
 
R

Robert Klemme

2010/1/20 Xeno Campanoli said:
I'm looking for a way to make sure an object being passed is in some clas= s
family, or to say it otherwise, inherits some specific class, but not
necessarily directly. =A0In fact, it could be a great-great-grandparent c= lass,
and that would be okay, and needs to be okay. =A0Is there something where= I
can take an object and go

unless object.inherits?(MyClass)
=A0 =A0 =A0 =A0raise SyntaxError, "etc."
end

First of all that would not be a SyntaxError because the syntax is not
affected. Using this error type will create misleading error
messages.

Here are all the ways that I am aware of (trying to summarize what
others have posted so far):

irb(main):010:0> a =3D []
=3D> []
irb(main):011:0> a.class.ancestors
=3D> [Array, Enumerable, Object, Kernel, BasicObject]
irb(main):012:0> a.class.ancestors.include? Enumerable
=3D> true
irb(main):013:0> a.kind_of? Enumerable
=3D> true
irb(main):014:0> a.is_a? Enumerable
=3D> true
irb(main):015:0> Enumerable =3D=3D=3D a
=3D> true
irb(main):016:0>

Note that I do not recommend using the test from line 12 as it is
likely much more inefficient than the other ones. The test from line
15 is especially suited for use with "case" statements as in

case a
when Enumerable
puts "it's enumerable"
when Array, Hash
puts "It's a special enumerable"
when Integer
puts "You can count on me."
else
puts "No idea about a."
end

Another note: more often than not it is not necessary to test for the
type of an object. You rather invoke those methods on it that you
expect it to implement. You will get an exception anyway if the
object does not implement the method (NoMethodError). You can find
more details about this concept under the label "duck typing", e.g.
http://en.wikipedia.org/wiki/Duck_typing

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
R

Robert Klemme

2010/1/20 Shot (Piotr Szotkowski) said:
Robert Klemme:
irb(main):010:0> a =3D []
=3D> []
[=85]

irb(main):015:0> Enumerable =3D=3D=3D a
=3D> true
Note that I do not recommend using the test from line 12 as it is
likely much more inefficient than the other ones. =A0The test from line
15 is especially suited for use with "case" statements as in
case a
when Enumerable
=A0 puts "it's enumerable"
when Array, Hash
=A0 puts "It's a special enumerable"
when Integer
=A0 puts "You can count on me."
else
=A0 puts "No idea about a."
end

A minor nitpick: Note that due to case=92s behaviour (once a =91when=92
matches, other =91whens=92 are ignored), the above will almost never=B9
print =91It's a special enumerable=92, as Arrays and Hashes are almost
always=B9 Enumerable. Testing for Array/Hash first and Enumerable
second would make more sense in most cases.

Oh, yes of course! Thanks for catching that! The order should have
been reversed.

case a
when Array, Hash
puts "It's a special enumerable"
when Enumerable
puts "it's enumerable"
when Integer
puts "You can count on me."
else
puts "No idea about a."
end

Thanks again!

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
X

Xeno Campanoli

Robert said:
First of all that would not be a SyntaxError because the syntax is not
affected. Using this error type will create misleading error
messages.

If I want a method that only takes objects of family Xclass, and I get one
passed that is not in that family, isn't that a syntax error? Bad type passed
in that argument place? What's the difference between that and passing a string
when it needs say an array?
Here are all the ways that I am aware of (trying to summarize what
others have posted so far):

irb(main):010:0> a = []
=> []
irb(main):011:0> a.class.ancestors
=> [Array, Enumerable, Object, Kernel, BasicObject]
irb(main):012:0> a.class.ancestors.include? Enumerable
=> true
irb(main):013:0> a.kind_of? Enumerable
=> true
irb(main):014:0> a.is_a? Enumerable
=> true
irb(main):015:0> Enumerable === a
=> true
irb(main):016:0>

Note that I do not recommend using the test from line 12 as it is
likely much more inefficient than the other ones. The test from line
15 is especially suited for use with "case" statements as in

Thank you. That is the kind of answer I really needed.

Sincerely, Xeno
 
W

Walton Hoops

If I want a method that only takes objects of family Xclass, and I get
one passed that is not in that family, isn't that a syntax error? Bad
type passed in that argument place? What's the difference between
that and passing a string when it needs say an array?

Nope, that's an ArgumentError. Example:
irb(main):001:0> Integer("boo")
ArgumentError: invalid value for Integer: "boo"
from (irb):2
irb(main):002:0>

Integer("boo") syntactically correct, yet "boo" is not a valid argument
for this function.
 
W

Walton Hoops

Nope, that's an ArgumentError. Example:
irb(main):001:0> Integer("boo")
ArgumentError: invalid value for Integer: "boo"
from (irb):2
irb(main):002:0>

Integer("boo") syntactically correct, yet "boo" is not a valid
argument for this function.
Whoops, my bad, actually the situation you describe is a TypeError:
irb(main):002:0> Integer([1,2,3])
TypeError: can't convert Array into Integer
from (irb):3
irb(main):003:0>

again, still syntactically sound, but Integer can't take an array.
 
X

Xeno Campanoli

Walton said:
Nope, that's an ArgumentError. Example:
irb(main):001:0> Integer("boo")
ArgumentError: invalid value for Integer: "boo"
from (irb):2
irb(main):002:0>

Integer("boo") syntactically correct, yet "boo" is not a valid
argument for this function.
Whoops, my bad, actually the situation you describe is a TypeError:
irb(main):002:0> Integer([1,2,3])
TypeError: can't convert Array into Integer
from (irb):3
irb(main):003:0>

again, still syntactically sound, but Integer can't take an array.

Okay. Good. Thanks. I appreciate the feedback. This will help my programming,
perhaps semantically I guess I should say.

Sincerely, Xeno
 
R

Robert Klemme

2010/1/21 Xeno Campanoli said:
Walton said:
On 1/20/2010 12:05 PM, Xeno Campanoli wrote:

Robert Klemme wrote:

2010/1/20 Xeno Campanoli <[email protected]>:
First of all that would not be a SyntaxError because the syntax is no= t
affected. =A0Using this error type will create misleading error
messages.

If I want a method that only takes objects of family Xclass, and I get
one passed that is not in that family, isn't that a syntax error? =A0B= ad type
passed in that argument place? =A0What's the difference between that a= nd
passing a string when it needs say an array?

Nope, that's an ArgumentError. =A0Example:
irb(main):001:0> Integer("boo")
ArgumentError: invalid value for Integer: "boo"
=A0 =A0 =A0 =A0from (irb):2
irb(main):002:0>

Integer("boo") syntactically correct, yet "boo" is not a valid argument
for this function.
Whoops, my bad, actually the situation you describe is a TypeError:
irb(main):002:0> Integer([1,2,3])
TypeError: can't convert Array into Integer
=A0 =A0 =A0 =A0from (irb):3
irb(main):003:0>

again, still syntactically sound, but Integer can't take an array.

Okay. =A0Good. =A0Thanks. =A0I appreciate the feedback. This will help my
programming, perhaps semantically I guess I should say.

Actually I would be less strict about the question whether a
TypeError, an ArgumentError or a NoMethodError is most appropriate
because I either do not catch any of them or just StandardError. Even
then the important information for me is in the stack trace and not so
much in the exception type. But that's probably because I create
smaller apps with scripting character most of the time. It does make
sense to think about this a little more (but not too much) when
creating larger apps.

I tend to use ArgumentError for wrong arguments because that seems the
most general description of what happened. A NoMethodError will be
thrown automatically when applying Duck Typing (i.e. caused by a
method not understood by the receiver). I'd agree that in this case a
TypeError is probably most appropriate.

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,160
Messages
2,570,890
Members
47,423
Latest member
henerygril

Latest Threads

Top