Делегирование методов класса объекту в ruby - PullRequest
2 голосов
/ 15 февраля 2011

Я пытаюсь обернуть вызовы к одноэлементному в классе (потому что я не хочу, чтобы остальная часть кода знала, что они разговаривают с одноэлементным), и я посмотрел на модуль делегата.* В моем коде у меня есть что-то вроде этого:

class HideSingleton
  @@obj = SingletonClass.instance # x is an instance of SingletonClass
  # I want to be able to say HideSingleton.blah,
  # where 'blah' is instance method of SingletonClass instance (i.e., 'x')
  SimpleDelegator.new @@obj.field
end

class SingletonClass < BaseClass
  attr_reader :field
  def initialize
    @field = SimpleDelegator.new super(BaseClass Constructor params)
  end
end

Затем в irb:

> require 'singleton_class'
> x = SingletonClass.new
> x.blah  # 'blah' is a method that is present in BaseClass instance
> require 'hide_singleton'
> y = HideSingleton

Как я могу сделать y.blah?

Ответы [ 2 ]

1 голос
/ 15 февраля 2011

Я думаю, что есть более простая реализация того, что вы пытаетесь сделать, но для создания скрытого одноэлементного класса, который делегирует одноэлементному классу, вы можете сделать следующее:

require 'delegate'
require 'forwardable'

class BaseClass
  def blah
    puts 'hi'
  end
end

class SingletonClass < BaseClass
  attr_reader :field
  def initialize
    @field = SimpleDelegator.new(BaseClass.new)
  end
end

class HideSingleton
  def self.obj
    @@obj ||= SingletonClass.new.field
  end

  def self.method_missing *args
    obj.send *args
  end
end

Затем вы можете сделать следующие звонки:

x = SingletonClass.new
x.blah
hi
=> nil
HideSingleton.blah
hi
=> nil
0 голосов
/ 04 марта 2011

Есть некоторые ошибки, о которых нужно знать:

В самом классе HideSingleton все еще есть несколько методов (из Object и Module), и эти методы будут вызываться в HideSingleton, а не в SingletonClass.Например, если у нас были разные константы в таких классах, как это:

class SingletonClass < BaseClass
  SingletonConst = :foo
end

class HideSingleton
  HideConst = :bar
end

Тогда вызов констант метода класса для обоих классов приводит к:

SingletonClass.constants
  #=> [:SingletonConst]

HideSingleton.constants
  #=> [:HideConst]

То же самое верно для любогостандартных методов (const_get, class_eval, dup, response_to? и т. д.).Чтобы избежать этого, вам необходимо выгрузить методы в HideSingleton, которые вы хотите передать в SingletonClass (или явно переслать их).

...