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
Hi –
On Fri, 29 Aug 2008, [email protected] wrote:
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
[I seem to have added the letter ‘B’ to the subject line when I
replied, so I’m replying again without doing so.]
Hi –
On Fri, 29 Aug 2008, [email protected] wrote:
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
Hi –
On Fri, 29 Aug 2008, Patrick D. wrote:
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
==.
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
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
On Thu, Aug 28, 2008 at 8:59 PM, David A. Black [email protected]
wrote:
…the few times I want to do something only when x is an array.
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
Patrick D. wrote:
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
Patrick D. wrote:
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
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.
Hi –
On Fri, 29 Aug 2008, Patrick D. wrote:
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
Doug G. 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).
Hi –
On Fri, 29 Aug 2008, Patrick D. wrote:
That way, it’ll work not only with Arrays, but also with Lists and
(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
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
On Thu, Aug 28, 2008 at 5:53 PM, David A. Black [email protected]
wrote:
310 Object.class
you plug Array/Array in, you won’t. The reason is that all objects are
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
On Fri, Aug 29, 2008 at 10:16 PM, [email protected]
[email protected] wrote:
310 Object.class
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.
[email protected] wrote:
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’ talk1 given by Patrick Farley at
the MountainWest RubyConf 2008 could shed some further light into this.
Regards,
Matthias
On Fri, Aug 29, 2008 at 3:01 AM, Doug G. [email protected]
wrote:
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
Robert D. 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
On Fri, Aug 29, 2008 at 8:40 PM, Doug G. [email protected]
wrote:
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.
I believe that because of the case statement semantics it is necessary
to take the === bull by its horns relatively early.
The “I do not understand case” is a recurring theme after all
BTW I did not know about the JS === semantics, most unfortunate that
they are opposed.
R.
Doug G. wrote:
Robert D. 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!