如何在Ruby中获取Singleton&#39实例变量的克隆值?

时间:2016-08-31 09:58:25

标签: ruby-on-rails ruby

我有一些(有点自定义)单身,有attr_reader :data,其中包含哈希。

我想获取此数据,有时会添加特定值。 但是,当我将数据设置为变量时,结果是该变量在数据上包含 link ,而不是 copy

已更新 我的单身人士代码':

class Company
  FILE_PATH = "#{Rails.root}/config/company.yml"
  attr_reader :data
  def self.instance
    @instance ||= new
  end

  def self.path
    FILE_PATH
  end

  def save data
    File.open(FILE_PATH, 'w') { |file| file.write(data.to_yaml) }
    set_data
  end

  private
  def initialize
    set_data
  end

  def set_data
    @data = HashWithIndifferentAccess.new(YAML.load(File.read(FILE_PATH)))
  end
end

用法示例:

Company.instance.data[:bar]
 => nil 
foo = Company.instance.data
foo[:bar] = 'buzz'
Company.instance.data[:bar]
 => 'buzz' 

如何将数据副本放入变量?我尝过.dup.copy,但没有帮助。

UPD:我已尝试在instance上使用这些方法,而不是data。我的错。谢谢大家,他们回答了我。)

3 个答案:

答案 0 :(得分:2)

我已尝试使用.clone.dup,但他们似乎都适合我。

require 'singleton'

class MySingleton
    include Singleton
    attr_accessor :data
end

MySingleton.instance.data = {}
foo = MySingleton.instance.data
foo[:bar] = 'buzz'
puts foo # {:bar=>"buzz"}
puts MySingleton.instance.data # {:bar=>"buzz"}

MySingleton.instance.data = {}
foo = MySingleton.instance.data.dup # or .clone
foo[:bar] = 'buzz'
puts foo # {:bar=>"buzz"}
puts MySingleton.instance.data # {}

答案 1 :(得分:1)

我认为你正在混淆什么。

class MySingleton
  include Singleton
  attr_reader :data

  def initialize
    @data = {a: 1, b: 2}
  end
end

foo = MySingleton.instance.data.clone
#=> {:a=>1, :b=>2}
foo[:c] = 3
#=> 3
foo
#=> {:a=>1, :b=>2, :c=>3}
MySingleton.instance.data
#=> {:a=>1, :b=>2}

答案 2 :(得分:0)

Ruby中单例模式的概念随着时间的推移而发生了变化。使用include Singleton实现显式单例类已成为边缘练习。通常,你构造一个对象,例如。通过调用Object.new并使用其单例类Object.new.singleton_class,如下所示:

o = Object.new
class << o
  attr_reader :data
end

你有一个功能齐全的单身人士,有自定义选择器#data