Class#singleton_of

A

Ara.T.Howard

at the risk of totally annoying everyone on this list and not getting any real
work done for another day i'm posting some of the code i've scraped out of
this week's posts and throwing down a challenge to boot:

jib:~/eg/ruby > cat a.rb
class Class
def singleton
class << self; self; end
end
def singleton?
not self.ancestors.include? self
end
def inside_singleton?
singleton?
end
def singleton_of
if singleton?
m = %r/^(?:#<Class:)+(.*?)(>+)$/io.match inspect
singleton_name, brackets = m[1], m[2]
n = brackets.size - 1
klass = klass_stamp singleton_name
n.times{ klass = class << klass; self; end }
klass
else
nil
end
end
def klass_stamp hierachy
relatives = hierachy.split %r/::/
parent = Object
while((child = relatives.shift))
klass = parent.const_get child
parent = klass
end
klass
end
end

module M
class C
p singleton_of # => nil
class << self
p singleton_of # => M::C
class << self
p singleton_of # => #<Class:M::C>
class << self
p singleton_of # => #<Class:#<Class:M::C>>
end
end
end
end
end

#
# we now explode here
#
class << self
p singleton_of
end


jib:~/eg/ruby > ruby a.rb
nil
M::C
#<Class:M::C>
#<Class:#<Class:M::C>>
a.rb:28:in `const_get': wrong constant name #<Object:0xb7447a10 (NameError)
from a.rb:28:in `klass_stamp'
from a.rb:17:in `singleton_of'
from a.rb:54


the challenge is obviously to implement Class#singleton_of without parsing the
output of inspect or, at least so that it works for all cases. the return
value of Class#singleton_of ought to be pretty obivous - it's the thing on the
rhs of

class << any_object

release the hounds!

-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| renunciation is not getting rid of the things of this world, but accepting
| that they pass away. --aitken roshi
===============================================================================
 
F

Florian Groß

Ara.T.Howard said:
the challenge is obviously to implement Class#singleton_of without
parsing the
output of inspect or, at least so that it works for all cases.

So are you okay with using Ruby-DL? This is something that ought to be
reasonably easy with evil-ruby.
 
A

Ara.T.Howard

So are you okay with using Ruby-DL? This is something that ought to be
reasonably easy with evil-ruby.

does evil-ruby use ruby-dl then? ruby-dl should be portable right? if so -
sure!

cheers.

-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| renunciation is not getting rid of the things of this world, but accepting
| that they pass away. --aitken roshi
===============================================================================
 
F

Florian Groß

does evil-ruby use ruby-dl then?
Yup.

ruby-dl should be portable right?

Mostly, I remember it still having some trouble on 64 bit platforms, but
I'm not sure how the issue has progressed lately.
 
A

Ara.T.Howard

So are you okay with using Ruby-DL? This is something that ought to be
reasonably easy with evil-ruby.

it came to me after only three beers late last night - and no evil-ruby! :

(note - i decided 'singleton_super' was a better name than 'singleton_of')


jib:~/eg/ruby > cat b.rb
module Kernel
alias __singleton_method_added singleton_method_added
def singleton_method_added(*a, &b)
obj = self
obj.singleton_class.class_eval{ @singleton_super = obj }
__singleton_method_added(*a, &b)
end
end

class Object
def singleton_class
@singleton_class ||= class << self;self;end
end
end

class Class
def singleton_super
class_eval{ def ________singleton_super_init;end } unless defined? @singleton_super
@singleton_super
end
end

class A
p singleton_super #=> nil
p singleton_class.singleton_super #=> A
class << self
p singleton_super #=> A
class << self
p singleton_super #=> #<Class:A>
end
end
end

class C < A
p singleton_super #=> nil
p singleton_class.singleton_super #=> C
class << self
p singleton_super #=> C
class << self
p singleton_super #=> #<Class:C>
end
end
end

class << [42]
p singleton_super #=> [42]
p singleton_class.singleton_super #=> #<Class:#<Array:0xb7436bfc>>
end

class << Class::new
p singleton_super #=> #<Class:0xb7436aa8>
end

class << Class::new(Class::new)
p singleton_super #=> #<Class:0xb7436814>
end

p singleton_class.singleton_super #=> #<Object:0xb7447a10 @singleton_class=#<Class:#<Object:0xb7447a10>>>



jib:~/eg/ruby > ruby b.rb
nil
A
A
#<Class:A>
nil
C
C
#<Class:C>
[42]
#<Class:#<Array:0xb7436bac>>
#<Class:0xb7436a58>
#<Class:0xb74367c4>
#<Object:0xb7447a10 @singleton_class=#<Class:#<Object:0xb7447a10>>>


can anyone break it?

cheers.

-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| renunciation is not getting rid of the things of this world, but accepting
| that they pass away. --aitken roshi
===============================================================================
 

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
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top