couchbase / couchbase-ruby-model

The Active Model implementation for Couchbase Server built on couchbase-ruby-client
61 stars 23 forks source link

Default Attributes Modified Through Instance Objects #6

Open ghost opened 11 years ago

ghost commented 11 years ago

Since Ruby relies heavily on references, directly modifying an attribute for an object using the default value will in some cases modify the default value instead of the instance object. Example:

class Foo < Couchbase::Model
  attribute :bar, :default => ::Hash.new
end

f1 = Foo.new
f1.bar[:test] # nil
f1.bar[:test] = 1

f2 = Foo.new
f2.bar[:test] # 1 - should be nil

Either the attribute method needs to be aware of this "gotcha" or it needs to be well-documented to use procs as a workaround:

class Foo < Couchbase::Model
  attribute :bar, :default => lambda {::Hash.new}
end

f1 = Foo.new
f1.bar[:test] # nil
f1.bar[:test] = 1

f2 = Foo.new
f2.bar[:test] # nil
avsej commented 11 years ago

For now you have to use lambda thing, but if you will make a library which will do genering __deep_copy__ accessible, I will be happy to use it. For example, you can take a look and maybe extract it from origin gem.