Error in ancestor?

R

Robert Dober

Hi list

I just observed this (and it cost me quite some effort to debug my code :( )

515/15 > ruby -ve 'class << Class::new; puts self; puts ancestors.inspect end'
ruby 1.8.5 (2006-12-04 patchlevel 2) [i686-linux]
#<Class:#<Class:0xb7dfae50>>
[Class, Module, Object, Kernel]


this seems to be in contradiction with
http://www.ruby-doc.org/core/classes/Module.html#M001700
stating
-----------------------------------------------------------------------------
mod.ancestors $B"*(B array

Returns a list of modules included in mod (including mod itself).
=============

module Mod
include Math
include Comparable
end

Mod.ancestors #=> [Mod, Comparable, Math]
Math.ancestors #=> [Math]
---------------------------------------------------------------------------

Is this an error in doc or in behavior?

Cheers
Robert
 
J

John Joyce

Hi list

I just observed this (and it cost me quite some effort to debug my
code :( )

515/15 > ruby -ve 'class << Class::new; puts self; puts
ancestors.inspect end'
ruby 1.8.5 (2006-12-04 patchlevel 2) [i686-linux]
#<Class:#<Class:0xb7dfae50>>
[Class, Module, Object, Kernel]


this seems to be in contradiction with
http://www.ruby-doc.org/core/classes/Module.html#M001700
stating
----------------------------------------------------------------------
-------
mod.ancestors $B"*(B array

Returns a list of modules included in mod (including mod itself).

=============

module Mod
include Math
include Comparable
end

Mod.ancestors #=> [Mod, Comparable, Math]
Math.ancestors #=> [Math]
----------------------------------------------------------------------
-----

Is this an error in doc or in behavior?

Cheers
Robert
What error?
It works as described ModuleName.ancestors returns an array
including itself and its ancestors.

irb(main):034:0> Array.ancestors
=> [Array, Enumerable, Object, Kernel]
irb(main):035:0> Class.ancestors
=> [Class, Module, Object, Kernel]

Perhaps it does blur the lines of the term module
Module
Mod
Module is the Class Name that recent versions of Ruby respond to, Mod
is apparently an old synonym that is still in the Rdoc, but Ruby
doesn't recognize it, it could be a mistake in the docs, but it could
also be an old alias...

irb(main):036:0> Mod.ancestors
NameError: uninitialized constant Mod
from (irb):36
from :0
irb(main):037:0> Module.ancestors
=> [Module, Object, Kernel]
 
R

Robert Dober

Hi list

I just observed this (and it cost me quite some effort to debug my
code :( )

515/15 > ruby -ve 'class << Class::new; puts self; puts
ancestors.inspect end'
ruby 1.8.5 (2006-12-04 patchlevel 2) [i686-linux]
#<Class:#<Class:0xb7dfae50>>
[Class, Module, Object, Kernel]


this seems to be in contradiction with
http://www.ruby-doc.org/core/classes/Module.html#M001700
stating
----------------------------------------------------------------------
-------
mod.ancestors $B"*(B array

Returns a list of modules included in mod (including mod itself).

=============

module Mod
include Math
include Comparable
end

Mod.ancestors #=> [Mod, Comparable, Math]
Math.ancestors #=> [Math]
----------------------------------------------------------------------
-----

Is this an error in doc or in behavior?

Cheers
Robert
What error?
This error
ruby -ve 'class << Class::new; puts ancestors.include?( self ) end'
ruby 1.8.5 (2006-12-04 patchlevel 2) [i686-linux]
false
Robert
 
M

Morton Goldberg

Hi list

I just observed this (and it cost me quite some effort to debug my
code :( )

515/15 > ruby -ve 'class << Class::new; puts self; puts
ancestors.inspect end'
ruby 1.8.5 (2006-12-04 patchlevel 2) [i686-linux]
#<Class:#<Class:0xb7dfae50>>
[Class, Module, Object, Kernel]


this seems to be in contradiction with
http://www.ruby-doc.org/core/classes/Module.html#M001700
stating
----------------------------------------------------------------------
-------
mod.ancestors $B"*(B array

Returns a list of modules included in mod (including mod itself).

=============

module Mod
include Math
include Comparable
end

Mod.ancestors #=> [Mod, Comparable, Math]
Math.ancestors #=> [Math]

It cost me some effort to figure out what the question really
was :), but I presume you're wondering why the singleton class
doesn't appear in the ancestor list. I don't know the answer, but I
think the question is posed more clearly when the example is
constructed for the singleton class of an ordinary object.

<code>
class Foo; end
Bar = class << Foo.new; self; end
Bar # => #<Class:#<Foo:0x20e18>>
Bar.ancestors # => [Foo, Object, Kernel]
</code>

If I had to make a call, I would say that the documentation had
inadvertently omitted a very special case.

Regards, Morton

P.S. Why 'puts ancestors.inspect' instead of the simpler 'p ancestors'?
 
J

John Joyce

Hi list

I just observed this (and it cost me quite some effort to debug my
code :( )

515/15 > ruby -ve 'class << Class::new; puts self; puts
ancestors.inspect end'
ruby 1.8.5 (2006-12-04 patchlevel 2) [i686-linux]
#<Class:#<Class:0xb7dfae50>>
[Class, Module, Object, Kernel]


this seems to be in contradiction with
http://www.ruby-doc.org/core/classes/Module.html#M001700
stating
---------------------------------------------------------------------
-
-------
mod.ancestors $B"*(B array

Returns a list of modules included in mod (including mod itself).

=============

module Mod
include Math
include Comparable
end

Mod.ancestors #=> [Mod, Comparable, Math]
Math.ancestors #=> [Math]
---------------------------------------------------------------------
-
-----

Is this an error in doc or in behavior?

Cheers
Robert
What error?
This error
ruby -ve 'class << Class::new; puts ancestors.include?( self ) end'
ruby 1.8.5 (2006-12-04 patchlevel 2) [i686-linux]
false
Robert
If you're expecting it to return true, it can't. Everything in the
array is an instance, not the class itself.
 
R

Robert Dober

Hi list

I just observed this (and it cost me quite some effort to debug my
code :( )

515/15 > ruby -ve 'class << Class::new; puts self; puts
ancestors.inspect end'
ruby 1.8.5 (2006-12-04 patchlevel 2) [i686-linux]
#<Class:#<Class:0xb7dfae50>>
[Class, Module, Object, Kernel]


this seems to be in contradiction with
http://www.ruby-doc.org/core/classes/Module.html#M001700
stating
----------------------------------------------------------------------
-------
mod.ancestors $B"*(B array

Returns a list of modules included in mod (including mod itself).

=============

module Mod
include Math
include Comparable
end

Mod.ancestors #=> [Mod, Comparable, Math]
Math.ancestors #=> [Math]

It cost me some effort to figure out what the question really
was :), but I presume you're wondering why the singleton class

I know in ruby I would say
assert didactic_skills.zero? # :(
doesn't appear in the ancestor list. I don't know the answer, but I
think the question is posed more clearly when the example is
constructed for the singleton class of an ordinary object.

<code>
class Foo; end
Bar = class << Foo.new; self; end
Bar # => #<Class:#<Foo:0x20e18>>
Bar.ancestors # => [Foo, Object, Kernel]
</code>

Sure thanks for adding this
If I had to make a call, I would say that the documentation had
inadvertently omitted a very special case.
Very probable given the code in class.c
Regards, Morton

P.S. Why 'puts ancestors.inspect' instead of the simpler 'p ancestors'?

Because output is shorter and more readable. I often get bitten by
debugging output
puts ary1
puts ary2
### Where the heck does ary2 start?

so I developed a reflex to use inspect for all kind of
debugging/demonstrating output.
I feel it is goo[df] practice.

Cheers
Robert
 
R

Robert Dober

If you're expecting it to return true, it can't. Everything in the
array is an instance, not the class itself.
Getting bitten by my didactic skills ;)
John please have a look at Morton's code, he was so kind to explain
what I am worried about much clearer.
That said maybe I can make things clearer myself:
irb(main):001:0> a = class A; ancestors end
=> [A, Object, Kernel]
irb(main):002:0> a.include? A
=> true
irb(main):003:0> B = Class::new
=> B
irb(main):004:0> Bsingle = class << B ; self end
=> #<Class:B>
irb(main):005:0> b = Bsingle.ancestors
=> [#<Class:B>, #<Class:Object>, Class, Module, Object, Kernel]
#Ah too bad my patched Ruby, I gotta recompile, sorry, normally the
singletons are #not in ancestor, please execute the code yourself to
see the difference.
irb(main):006:0> b.include? Bsingle
=> true

Cheers
Robert
 
M

Morton Goldberg

P.S. Why 'puts ancestors.inspect' instead of the simpler 'p
ancestors'?

Because output is shorter and more readable. I often get bitten by
debugging output
puts ary1
puts ary2
### Where the heck does ary2 start?

so I developed a reflex to use inspect for all kind of
debugging/demonstrating output.
I feel it is goo[df] practice.

But isn't 'p <expression>' shorthand for 'puts
(<expression>).inspect'? If this is the case and AFAIK it is, then
you just need to develop a new reflex to use p.

Regards, Morton
 
R

Robert Dober

P.S. Why 'puts ancestors.inspect' instead of the simpler 'p
ancestors'?

Because output is shorter and more readable. I often get bitten by
debugging output
puts ary1
puts ary2
### Where the heck does ary2 start?

so I developed a reflex to use inspect for all kind of
debugging/demonstrating output.
I feel it is goo[df] practice.

But isn't 'p <expression>' shorthand for 'puts
(<expression>).inspect'? If this is the case and AFAIK it is, then
you just need to develop a new reflex to use p.
Ah you said p, not puts, that's quite clever...
LOL you are an eagle eye, but you are right of course.
Robert
And yes you can chose the f above ;)
 
J

John Joyce

P.S. Why 'puts ancestors.inspect' instead of the simpler 'p
ancestors'?

Because output is shorter and more readable. I often get bitten by
debugging output
puts ary1
puts ary2
### Where the heck does ary2 start?

so I developed a reflex to use inspect for all kind of
debugging/demonstrating output.
I feel it is goo[df] practice.

But isn't 'p <expression>' shorthand for 'puts
(<expression>).inspect'? If this is the case and AFAIK it is, then
you just need to develop a new reflex to use p.
Ah you said p, not puts, that's quite clever...
LOL you are an eagle eye, but you are right of course.
Robert
And yes you can chose the f above ;)
Regards, Morton
Actually p is more like a short form for
puts object.inspect
 
M

Morton Goldberg

Actually p is more like a short form for
puts object.inspect

I admit that's more strictly accurate, but I find it very close to a
distinction without a difference since I can't think of a case where
(<expression>) doesn't evaluate to an object.

Regards, Morton
 
S

Sylvain Joyeux

I launched a discussion about this on Ruby-core. I think there were no
consensus on this at the time.

See ruby-core:9604. Tom closed the related bug, but maybe I should re-open
it since, as far as I remember, there has been no final conclusion.
 
R

Robert Dober

I launched a discussion about this on Ruby-core. I think there were no
consensus on this at the time.

See ruby-core:9604. Tom closed the related bug, but maybe I should re-open
it since, as far as I remember, there has been no final conclusion.
Merci Sylvain

I do not want to argue with the wise guys if it is an error - I
clearly thought so but that is not important ;)
But it really would have saved me an hour of debugging if the doc
stated clearly that singletons are not included. I thought this might
help others and as it took me 20s to vim the missing line into class.c
- I sent it up to core.

Do you think I should handle this differently?


Cheers
Robert
 
R

Rick DeNatale

I do not want to argue with the wise guys if it is an error - I
clearly thought so but that is not important ;)
But it really would have saved me an hour of debugging if the doc
stated clearly that singletons are not included. I thought this might
help others and as it took me 20s to vim the missing line into class.c

As far as I can tell, singleton classes aren't mentioned in the doc.
The documentation borders on folklore.

Singletons as a means of implementing both individual instance, and
class behavior have a position like "the man behind the curtain" in
"The Wizard of OZ." We're really supposed to disregard them. <G>

Coming from a background in Smalltalk, my preference would be if this
machinery were more visible and official, but Matz has his reasons for
not doing so. For one thing, not documenting it, and hiding it from
methods like ancestors and class makes it easier to tinker with as the
language evolves without "officially" breaking backward compatibility.

I wrote a bit more about this a couple of months ago
http://frodo:4072/articles/2007/04/23/ideas-for-improving-ruby

look in the section "Free the metaclass"

But those are just my opinions, I'm just glad I'm here!
 
D

dblack

Hi --

As far as I can tell, singleton classes aren't mentioned in the doc.
The documentation borders on folklore.

Singletons as a means of implementing both individual instance, and
class behavior have a position like "the man behind the curtain" in
"The Wizard of OZ." We're really supposed to disregard them. <G>

Coming from a background in Smalltalk, my preference would be if this
machinery were more visible and official, but Matz has his reasons for
not doing so. For one thing, not documenting it, and hiding it from
methods like ancestors and class makes it easier to tinker with as the
language evolves without "officially" breaking backward compatibility.

Does that mean that no one who's ever used Smalltalk can ever think
that it's right for Ruby to deviate from Smalltalk? :) I ask in a
humorous spirit -- and also because it gives me an excuse to mention:

http://www.infoq.com/articles/coming-from-ruby

:)

I think the singleton class has always had a somewhat equivocal
position. I tend to root for it being treated as a real class, if a
somewhat special-purposed one, since it *is* a real class (and neither
virtual nor meta). That could change, of course. Matz has always
described it as just the way that per-object behavior happens to be
implemented in Ruby -- and a case could certainly be made that classes
are an odd choice for that, since, while there are no hard-and-fast
rules about it, the first things most of us probably think of are
instantiation and inheritance and such, none of which can happen with
a singleton class.

Kernel#singleton_class would help a lot... or #singleton_module, if it
goes in that direction :)


David

--
* Books:
RAILS ROUTING (new! http://safari.awprofessional.com/9780321509246)
RUBY FOR RAILS (http://www.manning.com/black)
* Ruby/Rails training
& consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
 
R

Rick DeNatale

g-ruby

Au contraire mon frere. Le d=E9faut =E9tait le mien

For some reason something in my server config messed up the workings
of ProxyPass reverse, and I was seeing the local hostname and port,
and forgot to check when I cut and pasted from my browser.

Just a publically failed unit test. ;-(

--=20
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/
 
D

dblack

Hi --

Well David,

In short, NO.

Yesterday I was mulling over three or four topics to write about, your post
tipped me over, so after a day of thought and editting the longish:

http://talklikeaduck.denhaven2.com/articles/2007/06/21/where-i-come-from

Cool -- I'm glad. (BTW there's an unclosed emphasis tag or something,
causing about the last 1/3 to be in bold.) The points at the end are
especially interesting, about metaprogramming and such in Ruby as
opposed to Smalltalk, and Alan Kay's comment "that he was disappointed
that so few Smalltalkers experimented with changing and extending
Smalltalk by building off of the mechanisms of Class, Metaclass, and
Behavior." I've actually been, perhaps not disappointed but puzzled,
at the form some of this activity takes -- or doesn't take -- in the
Ruby world. In particular, the needle sometimes seems to be stuck in
the groove of certain ways of looking at the matter of changing and/or
amending the behavior of core-class objects. People are definitely
interested, for example, in the idea of having a way to do
block-scoped (or something-scoped) modifications to core classes; but
I think I've literally never heard anyone report actually having used
any of the libraries that let one do this. And in my opinion 'extend'
is massively underutilized; it really could be the answer to almost
every case of wanting to have, say, an Array that can shuffle itself,
or whatever.

As for singleton classes: I still strongly root for
Kernel#singleton_class. I find that people understand the whole thing
quite readily when it's explained to them that every object has (a) a
"birth" class and (b) a class of its own where it can stash methods
that only it can call. And it all falls into place except that you
have to go through the class << self; self; end thing to get at the
class, and that makes it feel like a second-class (ha ha) citizen.
(Hmmm... therein might lie another essay.... :)


David

--
* Books:
RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
RUBY FOR RAILS (http://www.manning.com/black)
* Ruby/Rails training
& consulting: Ruby Power and Light, LLC (http://www.rubypal.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

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top