Alexey Suslyakov Alexey Suslyakov - 3 months ago 11
Ruby Question

How to get cloned value of Singleton's instance variable in Ruby?

I've some (a bit custom)singleton, that has

attr_reader :data
, which contains Hash.

I want to get this data and sometimes add there specific values.
But when I set data into variable, it turns out, that variable contains link on data, not the copy.

UPDATED
Code of my 'singleton':

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


Usage example:

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


How can I put copy of data to variable? I've tried
.dup
and
.copy
, but it didn't help.

(UPD: I've tried to use these methods on
instance
, not on
data
. My fault. Thanks everyone, who answered to me.)

Answer

I think you're mixing something up.

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}