Reputation: 104089
Is it possible in Ruby to define a new non-singleton class based on a singleton class?
I tried something like this (snip):
module SomeModule
extend self
class Singleton;end
end
class NonSingleton
include SomeModule
end
nonsingleton = NonSingleton.new
But of course to you gurus it's already evident that this won't work as I expected.
Basically what I want is to re-use the functionality of the Singleton class, without affecting it's behavior in any way. Is it possible?
After further investigation, it would seem that this ain't possible at all (please correct me if I'm wrong). Would a hack like following be too fugly/messy?
singleton = File.read('some_singleton.rb')
non_singleton = eval(singleton.gsub('include Singleton', ''))
# Or perhaps:
non_singleton = eval(singleton.gsub('module SomeModule', 'module MyOwnModule'))
Upvotes: 0
Views: 556
Reputation: 123662
OK. I don't have real ruby here, only IronRuby, but this is what happens when I try to do it:
# define a new object
>>> s = "hello"
=> "hello"
# add a method to it's singleton class
>>> class << s
... def say; puts self; end
... end
=> nil
# get it's singleton class
>>> SingletonBaseClass = class << s; self; end
=> #<Class:#<String:0x000005c>>
# try build a new one inheriting from the singleton class
>>> class NonSingletonClass < SingletonBaseClass
... end
:0: can't make subclass of virtual class (TypeError)
IronRuby is fairly compliant with the normal ruby language itself, I'd be willing to bet that a similar error message would happen in real ruby. In short, you can't do it.
This begs the question: what are you trying to do? If a singleton class for a particular object is getting complicated enough that you want to re-use it, shouldn't you just be putting that code in a regular class or module?
For example, you could do this:
# define our reusable code
module SharedMethods
def a;end
def b;end
# and so on
end
# mix it into the singleton of some object
s = "hello"
class << s; include SharedMethods; end
You could then re-use it on any other object/class/etc
Upvotes: 1