tags:

views:

365

answers:

1

Hi,

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'))
+1  A: 

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

Orion Edwards
Thanks, I tried that too, and it gave me the same error. I want to have different inflection rule sets on Rails, and for that I need to re-use ActiveSupport::Inflector::Inflections.
Ivan
I think he means a singleton as in "include Singleton", not an eigenclass.
Chuck
Darn. I always did think it was a bad idea to call the meta/eigenclass "singleton class"
Orion Edwards