Создание нового не синглтон-класса на основе одноэлементного класса - PullRequest
0 голосов
/ 17 марта 2009

Возможно ли в Ruby определить новый не-одноэлементный класс на основе одноэлементного класса?

Я пробовал что-то вроде этого (отрывок):

module SomeModule
  extend self
  class Singleton;end
end

class NonSingleton
  include SomeModule
end
nonsingleton = NonSingleton.new

Но, конечно, для вас, гуру, уже очевидно, что это не сработает, как я ожидал.

По сути, я хочу повторно использовать функциональность класса Singleton, не затрагивая его поведение каким-либо образом. Возможно ли это?

После дальнейшего расследования может показаться, что это вообще невозможно (пожалуйста, поправьте меня, если я ошибаюсь). Будет ли хак вроде следования слишком беспорядочным / грязным?

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 Ответ

1 голос
/ 18 марта 2009

OK. У меня нет настоящего рубина, только IronRuby, но вот что происходит, когда я пытаюсь это сделать:

# 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 довольно совместим с обычным языком рубина, и я готов поспорить, что подобное сообщение об ошибке будет происходить в реальном рубине. Короче говоря, вы не можете этого сделать.

Напрашивается вопрос: что вы пытаетесь сделать? Если одноэлементный класс для конкретного объекта становится достаточно сложным, и вы хотите использовать его повторно, не следует ли просто поместить этот код в обычный класс или модуль?

Например, вы можете сделать это:

# 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

Затем вы можете повторно использовать его для любого другого объекта / класса / и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...