Class ===

R

RubyTalk

I need help with === and Objects

270 Array === Array
] false [< 290 Array == Array
] true [< 300 Object === Object
] true [< 310 Object.class
] Class [< 320 Object === Class
] true [<


I would think that Array === Array. If not I would not expect line 300
to be true.

Thanks for any help,
Becker
 
D

David A. Black

Hi --

I need help with === and Objects

270 Array === Array
] false [< 290 Array == Array
] true [< 300 Object === Object
] true [< 310 Object.class
] Class [< 320 Object === Class
] true [<


I would think that Array === Array. If not I would not expect line 300
to be true.

Those are two very different cases, though. Given this:

a === b

it is true if the class of b has a in its ancestry. So you can always
try:

b.class.ancestors.include?(a)

If you plug Object/Object into that expression, you'll get true. If
you plug Array/Array in, you won't. The reason is that all objects are
instances of Object and its descendants, including the class object
Object. So Object has a unique relationship, among classes, to itself.


David
 
P

Patrick Doyle

and I would also like to know why

x = Array.new()
=> []
x === Array
=> false

I've just got to teach to use:

case x
when Array
...
end

instead of
if x === Array
...
end

...the few times I want to do something only when x is an array.

--wpd
 
D

David A. Black

[I seem to have added the letter 'B' to the subject line when I
replied, so I'm replying again without doing so.]

Hi --

I need help with === and Objects

270 Array === Array
] false [< 290 Array == Array
] true [< 300 Object === Object
] true [< 310 Object.class
] Class [< 320 Object === Class
] true [<


I would think that Array === Array. If not I would not expect line 300
to be true.

Those are two very different cases, though. Given this:

a === b

it is true if the class of b has a in its ancestry. So you can always
try:

b.class.ancestors.include?(a)

If you plug Object/Object into that expression, you'll get true. If
you plug Array/Array in, you won't. The reason is that all objects are
instances of Object and its descendants, including the class object
Object. So Object has a unique relationship, among classes, to itself.


David
 
D

David A. Black

Hi --

and I would also like to know why

x = Array.new()
=> []
x === Array
=> false

Because the instance method Array#=== is not defined as a test of
class membership. I believe it's the default ===, which is the same as
==.
I've just got to teach to use:

case x
when Array
...
end

instead of
if x === Array
...
end

...the few times I want to do something only when x is an array.

You can do:

if Array === x

=== is the case equality operator, so this:

case obj
when x

is like this:

if x === obj


David
 
D

Doug Glidden

Patrick said:
and I would also like to know why

x = Array.new()
=> []
x === Array
=> false

I've just got to teach to use:

case x
when Array
...
end

instead of
if x === Array
...
end

...the few times I want to do something only when x is an array.

--wpd

Forgive me if I'm missing something obvious, but wouldn't it be a whole
lot more logical to do this?

if x.is_a? Array
...
end

- Doug
 
P

Patrick Doyle

Hi --
and I would also like to know why

x = Array.new()
=> []
x === Array
=> false
I've just got to teach [myself] to use:

case x
when Array
...
end

instead of
if x === Array
...
end

...the few times I want to do something only when x is an array.

You can do:

if Array === x

=== is the case equality operator, so this:

case obj
when x

is like this:

if x === obj

Ahhh.... that makes perfect sense! (And I mean that in the "light
dawns on marble head" sort of way, not in the sarcastic sort of way.)

Thanks....

BTW... I've not had any luck Googling "ruby === class type" sorts of
stuff. So I just figured I would have to live w/o knowing the answer
to this puzzling question.

And now I know the answer.

And the answer makes intuitive sense.

Life is good.

Thanks again :)

--wpd
 
P

Patrick Doyle

Forgive me if I'm missing something obvious, but wouldn't it be a whole
lot more logical to do this?

if x.is_a? Array
...
end
yup... that makes good sense too.

This is a great night! :)

--wpd
 
D

David A. Black

Hi --

BTW... I've not had any luck Googling "ruby === class type" sorts of
stuff. So I just figured I would have to live w/o knowing the answer
to this puzzling question.

If you ever want or need to, you can google for ruby "case equality"
and you'll find links.
And now I know the answer.

And the answer makes intuitive sense.

Life is good.

Thanks again :)

Glad to help!


David
 
D

Doug Glidden

Patrick said:
yup... that makes good sense too.

This is a great night! :)

--wpd

Even better, if its possible you'd want to use the method on a structure
other than an array in the future, use 'respond-to?' instead. So for
instance, if you're protecting a call to 'each':

if x.respond_to? :each
x.each do
...
end
end

That way, it'll work not only with Arrays, but also with Lists and
Hashes or any other Enumerable class (or any class that implements
each). So if you later on decide that it would make more sense to store
your data in a List instead of an Array, if you use 'is_a?' you'll have
to go through and change your code every time you do this check, but if
you use 'respond_to?', you won't have to change a single line!

Of course, there are situations where 'is_a?' is necessary, but
'respond_to?' is generally preferable, from what I've seen.
 
D

Doug Glidden

Doug Glidden wrote:
[snip]
That way, it'll work not only with Arrays, but also with Lists and
Hashes or any other Enumerable class (or any class that implements
each). So if you later on decide that it would make more sense to store
your data in a List instead of an Array, if you use 'is_a?' you'll have
to go through and change your code every time you do this check, but if
you use 'respond_to?', you won't have to change a single line!
[snip]

Oops, I think that might have been a bad example—I don't think Ruby's
List class is actually the data structure known as a list—in any case,
it doesn't include Enumerable. Got my head in Java there for a second,
but you get the idea. There are LinkedList classes out there, though
(http://www.koders.com/ruby/fidCB5A463AB556F4FFD20E03139FF59563B118D108.aspx?s=socket
for example).

- Doug
 
P

Patrick Doyle

Even better, if its possible you'd want to use the method on a structure
other than an array in the future, use 'respond-to?' instead. So for
instance, if you're protecting a call to 'each':

if x.respond_to? :each
x.each do
...
end
end

That way, it'll work not only with Arrays, but also with Lists and
Hashes or any other Enumerable class (or any class that implements
each). So if you later on decide that it would make more sense to store
except...

#each doesn't always mean the same thing to everybody.

For Hashes, it means "each key and value pair" for arrays, it means
"each value, but without the index". On my TODO list is to figure out
what (virtual) paperwork is required to propose the addition of an
#each_element method that _would_ mean the same thing to everybody.
(For Arrays, it would be aliased to #each, for Hashes, it would be
aliased to #each_value, for a hypothetical List class, it would be
aliased to some iterator that yields the next element in the list.

--wpd
 
D

David A. Black

Hi --

except...

#each doesn't always mean the same thing to everybody.

For Hashes, it means "each key and value pair" for arrays, it means
"each value, but without the index". On my TODO list is to figure out
what (virtual) paperwork is required to propose the addition of an
#each_element method that _would_ mean the same thing to everybody.
(For Arrays, it would be aliased to #each, for Hashes, it would be
aliased to #each_value, for a hypothetical List class, it would be
aliased to some iterator that yields the next element in the list.

"Element" doesn't have a universal meaning either, though. It might be
better to think of normalizing things at the calling level:

do_something_each_based(hash.values)

etc.


David

--
Rails training from David A. Black and Ruby Power and Light:
Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
Advancing with Rails January 19-22 Fort Lauderdale, FL *
* Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!
 
R

RubyTalk

[I seem to have added the letter 'B' to the subject line when I
replied, so I'm replying again without doing so.]

Hi --

I need help with === and Objects

270 Array === Array
] false [<

290 Array == Array
] true [<

300 Object === Object
] true [<

310 Object.class
] Class [<

320 Object === Class
] true [<


I would think that Array === Array. If not I would not expect line 300
to be true.

Those are two very different cases, though. Given this:

a === b

it is true if the class of b has a in its ancestry. So you can always
try:

b.class.ancestors.include?(a)

If you plug Object/Object into that expression, you'll get true. If
you plug Array/Array in, you won't. The reason is that all objects are
instances of Object and its descendants, including the class object
Object. So Object has a unique relationship, among classes, to itself.


David

--
Rails training from David A. Black and Ruby Power and Light:
Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
Advancing with Rails January 19-22 Fort Lauderdale, FL
See http://www.rubypal.com for details and updates!

I guess the thing i still struggle with is these lines:

The reason is that all objects are instances of Object and its
descendants, including the class object Object. So Object has a unique
relationship, among classes, to itself.

Mostly the " the class object Object"

Is there a visual representation of this? It might help me understand..

Thanks
Becker
 
R

Robert Dober

if x.is_a? Array
...
end

This is OT but as OP got lots of useful information already ;).

Actually I much prefer
A === x
to
x.is_a? Array

Proof ;)
Let us assume I am not a native English speaker, surely I prefer the
symbolic name to
the sophisticated auxiliary verb "to be" which happens to be irregular
too, cans I has a Grammar please !!! and the indefinite article "a".
If OTOH I were a native speaker I would be quite shocked that it reads
is_a? instead of is_an?, would I not? (not! is not a method name!, as
name! is not!.... ad infinitum)
Q.E.D.

Seriously #is_a? is more readable for sure but #=== has the advantage
to pinpoint the possibility of using a *case* statement.

Cheers
Robert
 
L

lasitha

I need help with === and Objects
270 Array === Array
] false [<
290 Array == Array
] true [<
300 Object === Object
] true [<
310 Object.class
] Class [<
320 Object === Class
] true [<
I guess the thing i still struggle with is these lines:
The reason is that all objects are instances of Object and its
descendants, including the class object Object. So Object has a unique
relationship, among classes, to itself.

Mostly the " the class object Object"

Not sure if i can explain this well but i'll take a shot at it.

Starting with the obvious, all objects have a class:
01> class X; end
--> nil
02> X.new.class
--> X

More interestingly, this applies to classes themselves too:
03> X.class
--> Class

In other words X is an instance of class.
Now, plain old objects are no different:
04> Object.new.class
--> Object
05> Object.class
--> Class

But Class itself is also an object (as David said, everything is an Object):
06> Class.ancestors
--> [Class, Module, Object, PP::ObjectMixin, Kernel]

So, coming back to your original example:
07> Object === Object
--> true

This is true because the class of Object is Class and Class is a
descendent of Object.

The key here (methinks) is that you are asking whether the _class of
Object_ is a descendent of Object.
Compare that to:
08> Object.new === Object
--> false

False because the class of an Object _instance_ is Object and that
isn't a descendent of Object.

Hope that didn't confuse you further!
Cheers,
lasitha.
 
M

Matthias Reitinger

The reason is that all objects are instances of Object and its
descendants, including the class object Object. So Object has a unique
relationship, among classes, to itself.

Mostly the " the class object Object"

Is there a visual representation of this? It might help me understand..

ri Class

Maybe the excellent `Ruby Internals' talk[1] given by Patrick Farley at
the MountainWest RubyConf 2008 could shed some further light into this.

Regards,
Matthias

[1]: http://mwrc2008.confreaks.com/11farley.html
 
D

Doug Glidden

Robert Dober wrote:
[snip]
Seriously #is_a? is more readable for sure but #=== has the advantage
to pinpoint the possibility of using a *case* statement.

Cheers
Robert

OT:

All true, but also consider the fact that === requires one to remember
what it means (=== vs. ==), which is not particularly intuitive (as
opposed to is_a?, which is a term most students get drilled into their
heads pretty much the first day of their first OO programming course).
The confusion is further compounded by the fact that (if I remember my
JS correctly) the functionality of === and == in Ruby are exactly
reversed from their functionality in JavaScript.

Doug
 
D

Doug Glidden

Doug said:
Robert Dober wrote:
[snip]
Seriously #is_a? is more readable for sure but #=== has the advantage
to pinpoint the possibility of using a *case* statement.

Cheers
Robert

OT:

All true, but also consider the fact that === requires one to remember
what it means (=== vs. ==), which is not particularly intuitive (as
opposed to is_a?, which is a term most students get drilled into their
heads pretty much the first day of their first OO programming course).
The confusion is further compounded by the fact that (if I remember my
JS correctly) the functionality of === and == in Ruby are exactly
reversed from their functionality in JavaScript.

Doug

Even more OT:

Of course, the beauty of Ruby is that they're both available, so you can
use whichever one makes more sense to you!
 

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

No members online now.

Forum statistics

Threads
474,201
Messages
2,571,049
Members
47,655
Latest member
eizareri

Latest Threads

Top