about finding subclasses

D

Dorren

for a given class, find all subclasses

i found the solution (by pit capitain) at
http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/e812c7cef446a96
, it works, but i don't understand it.
--------------------------------------------------------
require "enumerator"

def get_subclasses(klass)
ObjectSpace.enum_for:)each_object, class << klass; self;
end).to_a
end

-------------------------------------------------------

i don't understand what "class << klass; self; end" does. can someone
rewrite and make it longer?


Dorren
 
H

Harold Hausman

for a given class, find all subclasses

i found the solution (by pit capitain) at
http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/e812c7cef446a96
, it works, but i don't understand it.
--------------------------------------------------------
require "enumerator"

def get_subclasses(klass)
ObjectSpace.enum_for:)each_object, class << klass; self;
end).to_a
end

There are two potentially confusing bits about that very elegant piece of code.

One is the use of enumerator and enum_for, which can be pretty easily
unrolled. However, it may not be clear from that code that the hard
work is actually being done by ObjectSpace.each_object which accepts a
parameter to use as a 'filter'

The other confusing bit could be the use of the "class << object"
form, which is described as such (in the pickaxe):

... the class <<obj notation, which basically says "build me a new
class just for object obj." ...

Thats one way of putting it. Another way is presented in this article
(which is the explanation that makes the most sense to me):
http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html

Here is a 'longer' version of the above like you asked for, though,
I'm not sure it's any more clear:
#################################
class Object
# The hidden singleton lurks behind everyone
def metaclass
class << self
return self
end
end
end

def get_subclasses(klass)
the_subclasses = []

ObjectSpace.each_object( klass.metaclass ) do |object|
the_subclasses.push object
end

return the_subclasses
end

class A
end

class B < A
end

p get_subclasses( A )
#################################

Hope that helps,
-Harold
 
E

eden li

Dang, you beat me to it. I had typed up a similar response. Here's a
minor tweak though.

... the class <<obj notation, which basically says "build me a new
class just for object obj." ...

As far as I can tell, all objects (and thus all classes) already have
this singleton class. "class << klass; self; end" is just a way to
get at it. why's article defines Object#metaclass as an easy way to
shorthand this long form syntax.

So, it's pretty clear from the docs that ObjectSpace#each_object takes
a module/class as a filter and will return only objects which are
subclasses of said module/class. If you hand it a metaclass, it does
simply filters for objects which have metaclasses matching the same
criteria.
=> false

So ObjectSpace#each_object will end up returning only classes
subclassed from the given "klass" since #kind_of? will hold true for
only those objects matching that criteria.

I think. ;-)
 
D

Dorren

Metaclass, that's new to me.I have to re-read the pick-axe book and
that website, and has a little better understanding now.

Thanks all.

Dorren
 
R

Rick DeNatale

Dang, you beat me to it. I had typed up a similar response. Here's a
minor tweak though.



As far as I can tell, all objects (and thus all classes) already have
this singleton class. "class << klass; self; end" is just a way to
get at it.

Well logically at least. For regular objects a singleton class isn't
created until it's needed.

So:

a = "abc"
#at this point there is no singleton class for the instance of String
referenced by a
def a.foo
"foo"
end
#at this point it does, the singleton class was created to hold the method.

Of course you can't ever see the lack of a singleton class, at least
from ruby code, in order to do so requires an extension.

Classes get their singleton classes when they are created.
 
C

ChrisKaelin

Harold said:
for a given class, find all subclasses

i found the solution (by pit capitain) at
http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/e812c7cef446a96
, it works, but i don't understand it.
--------------------------------------------------------
require "enumerator"

def get_subclasses(klass)
ObjectSpace.enum_for:)each_object, class << klass; self;
end).to_a
end

There are two potentially confusing bits about that very elegant piece of code.

One is the use of enumerator and enum_for, which can be pretty easily
unrolled. However, it may not be clear from that code that the hard
work is actually being done by ObjectSpace.each_object which accepts a
parameter to use as a 'filter'

The other confusing bit could be the use of the "class << object"
form, which is described as such (in the pickaxe):

.. the class <<obj notation, which basically says "build me a new
class just for object obj." ...

Thats one way of putting it. Another way is presented in this article
(which is the explanation that makes the most sense to me):
http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html

Here is a 'longer' version of the above like you asked for, though,
I'm not sure it's any more clear:
#################################
class Object
# The hidden singleton lurks behind everyone
def metaclass
class << self
return self
end
end
end

def get_subclasses(klass)
the_subclasses = []

ObjectSpace.each_object( klass.metaclass ) do |object|
the_subclasses.push object
end

return the_subclasses
end

class A
end

class B < A
end

p get_subclasses( A )
#################################

Hope that helps,
-Harold

Wow, why's just twisted my brain... I will have to read his article
again in a few days, and the maybe again and again until I really may
get it... but now I just need a drink...
 

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,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top