Ruby on Rails: передача аргумента в синглтон - PullRequest
1 голос
/ 07 декабря 2009

У меня есть приложение Rails, которое постоянно общается с другим веб-сервером через оболочку, и я хотел бы вставить оболочку в класс Singleton, чтобы он не создавался заново для каждого запроса. Достаточно просто, подумал я:

class AppWrapper < Wrapper
  include Singleton
end
...
wrapper = AppWrapper.instance "url"

Только это не работает:

wrong number of arguments (0 for 1)
/usr/lib/ruby/1.8/singleton.rb:94:in `initialize'
/usr/lib/ruby/1.8/singleton.rb:94:in `new'
/usr/lib/ruby/1.8/singleton.rb:94:in `instance'

Wrapper.initialize нуждается в аргументе, и, очевидно, он не проходит, так как в рассматриваемой строке 94 написано

@__instance__ = new # look Ma, no argument

Как мне обойти это? Переопределение инициализации в AppWrapper, похоже, не помогает, и перебор с Wrapper для отделения "set URL" от "initialize" кажется неоптимальным.

Ответы [ 4 ]

2 голосов
/ 05 августа 2011

Передача аргумента в синглтон

class Parameterized_Singleton

def initialize(a)
  @pdf = a
  puts @pdf
end

def self.instance(p)

  begin
    @@instance  =Parameterized_Singleton.new(p)
    private_class_method :new
    rescue NoMethodError
     # return @@instance  # or you can return previous object
      puts "Object Already Created"
      exit
  end

  return @@instance
end

def scanwith(b)
  puts "scan"
end

def show_frequence_distribution
  puts "fd"
end

def show_object_number(a)
  puts "no"
end


end


Parameterized_Singleton.instance(20).show_object_number(10)
Parameterized_Singleton.instance(10).show_object_number(20)
1 голос
/ 05 марта 2011

Я задал этот вопрос, пока еще думал о Руби, и сейчас это кажется таким наивным. Простое решение - просто сохранить объект Wrapper в переменной-члене и использовать ||= для его инициализации, только если он еще не установлен:

class WrapperUserClass
  def initialize
     @wrapper = nil # Strictly speaking unnecessary, but it's a bit clearer this way
  end

  def wrapper
    @wrapper ||= Wrapper.new(foobar)
  end

  def do_something
    wrapper.booyakasha
  end
end
1 голос
/ 07 декабря 2009

Вы уверены, что вам нужен синглтон, а не завод? См. это

0 голосов
/ 07 декабря 2009

Поскольку вы упомянули что-то о редактировании Wrapper как решения, вы не можете просто использовать Wrapper напрямую и сделать это?

class Wrapper; include Singleton; end

Если нет, вы можете использовать что-то вроде этого, чтобы убедиться, что AppWrapper.new не вызывается более одного раза:

class AppWrapper
  def self.new(*args)
    class << app_wrapper = Wrapper.new(*args)
      include Singleton
    end
    app_wrapper
  end
end

Если вам нужен одноэлементный метод "Klass.instance", вам придется либо извлечь параметр из Wrapper # initialize, либо просто переопределить экземпляр Singleton #, чтобы он мог принимать аргументы и передавать их вызову new on линия 94.

...