【问题标题】:Ruby on Rails: Passing argument to singletonRuby on Rails:将参数传递给单例
【发布时间】:2009-12-07 06:04:32
【问题描述】:

我有一个 Rails 应用程序通过包装器反复与另一个 Web 服务器通信,我想将包装器粘贴在 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”分开似乎不是最理想的。

【问题讨论】:

    标签: ruby-on-rails ruby singleton argument-passing initialization


    【解决方案1】:

    将参数传递给单例

    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)
    

    【讨论】:

      【解决方案2】:

      你确定你需要一个单例而不是一个工厂吗?参考this

      【讨论】:

      • 应用程序永远不需要多个包装器,因此工厂似乎没有必要。
      【解决方案3】:

      当我还在琢磨 Ruby 时,我问了这个问题,现在它看起来很幼稚。简单的解决方案是将 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
      

      【讨论】:

        【解决方案4】:

        既然你提到了一些关于编辑 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#instance 以可选地获取参数并将它们传递给对 new on 的调用第 94 行。

        【讨论】:

        • 虽然我的应用永远不需要多个 Wrapper,但可以想象未来的应用可能需要同时连接到多个 Wrapper。是的,我确实需要实例方法,重点是无需为每次调用都重新创建对象即可访问 Wrapper。
        猜你喜欢
        • 1970-01-01
        • 2015-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-24
        • 1970-01-01
        • 1970-01-01
        • 2012-06-26
        相关资源
        最近更新 更多