AR clone interaction with initialization logic in model

All,

Assume an AR model with an after_initialize method, which is used to
initialize attribute values. An example would be:

class X < ActiveRecord::Base

def after_initialize
self.attr1 = 0
end
end

Further assume that x is an instance of X, and x.attr1 has been assigned
the value 3.

If I do y = x.clone, and interrogate the value of y.attr1, I’ll get 0.
This makes sense given the source code for AR#clone. But I expected the
value of attr1 to be 3, not 0.

I would think that clone should completely instantiate the new object,
and then assign the attribute values from the original object.

Is the current behavior a bug, or am I missing some important
philosophical point.

Thanks,
Wes

One way around this is to modify the after_initialize logic to not
assume that the attribute values should always be set, like so:

class X < ActiveRecord::Base

def after_initialize
if self.new_record?
self.attr1 ||= 0
end
end
end

In a clone situation, attr1 will already have a value and therefore,
won’t be initialized to a default value.

Still, I feel like clone has a bug in it. Here’s what happens in a
regular Ruby object:

class X
attr_accessor :val

def initialize
@val = 5
end
end

x = X.new
x.val
=> 5
x.val = 23
=> 23
y = x.clone
=> #<X:0x2c33148 @val=23>

The value of @val in the cloned object is 23, not 5.

While I concede that after_initialize is a standalone method that
officially has nothing to do with Ruby object initialization, I still
feel like the clone method should set the attribute values after the
object is instantiated.

Wes

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs