Yeah, I agree that it can be counter-intuitive and error-prone depending on
your background...

On Sun, Aug 14, 2016 at 3:24 PM, Tommy Hofmann <[email protected]> wrote:

> Yes, you are right.
>
> When we started with julia and did the deepcopy for our own types, we
> (apparently) did not read the manual and just overloaded the deepcopy
> function. This introduced lots of nasty bugs.
>
> On Sunday, August 14, 2016 at 9:15:46 PM UTC+2, Cedric St-Jean wrote:
>>
>> AFAIK deepcopy should never be overloaded. From the docstring:
>>
>> While it isn't normally necessary, user-defined types can override the
>>> default deepcopy behavior by defining a specialized version of the
>>> function deepcopy_internal(x::T, dict::ObjectIdDict) (which shouldn't
>>> otherwise be used), where T is the type to be specialized for, and dict
>>> keeps track of objects copied so far within the recursion. Within the
>>> definition, deepcopy_internal should be used in place of deepcopy, and
>>> the dict variable should be updated as appropriate before returning.
>>>
>>
>>
>> On Sun, Aug 14, 2016 at 3:03 PM, Tommy Hofmann <[email protected]> wrote:
>>
>>> But for users the following might be surprising: If a user defines
>>> deepcopy(::T) for a user defined type T and x is of type Array{T, 1}, then
>>> deepcopy(x) is not the "same" as [ deepcopy(z) for z in x]. At least this
>>> is my experience and how I understand deepcopy.jl.
>>>
>>>
>>> On Sunday, August 14, 2016 at 8:31:20 PM UTC+2, Cedric St-Jean wrote:
>>>>
>>>> instead, it puts the same object (which is a copy) in the first and
>>>>> third positions and you get the same behavior. Maybe this is not the
>>>>> intended behavior of deepcopy?
>>>>>
>>>>
>>>> It's intentional. deepcopy has to keep and update a dictionary as it
>>>> traverses the datastructure in order to provide the behaviour. Without it,
>>>> it would be impossible to copy cyclic data-structures, as the recursive
>>>> traversal would never end.
>>>>
>>>> On Sunday, August 14, 2016 at 11:36:04 AM UTC-4, Tommy Hofmann wrote:
>>>>>
>>>>> Indeed, the behavior of deepcopy with respect to arrays of user
>>>>> defined types is surprising.
>>>>>
>>>>> If you define
>>>>>
>>>>> Base.deepcopy_internal(x::MyType, ::ObjectIdDict) =
>>>>> MyType(deepcopy(x.a))
>>>>>
>>>>> then deepcopy(MyType_Vec[[1, 3, 1]]) gives a new object with
>>>>> "independent" elements. See also http://docs.julialang.org
>>>>> /en/release-0.4/stdlib/base/#Base.deepcopy
>>>>>
>>>>>
>>>>> On Friday, August 12, 2016 at 8:56:32 PM UTC+2, Josh Langsfeld wrote:
>>>>>>
>>>>>> For your second question, I would have expected just doing
>>>>>> deepcopy(MyType_Vec[[1,3,1]]) would have created a new array with a
>>>>>> new object allocated for each element. Instead, it puts the same object
>>>>>> (which is a copy) in the first and third positions and you get the same
>>>>>> behavior. Maybe this is not the intended behavior of deepcopy?
>>>>>>
>>>>>> You can easily get around though this by explicitly calling deepcopy
>>>>>> on each element directly: MyType_Vec = map(deepcopy,
>>>>>> MyType_Vec[[1,3,1]]). A similar alternative with an array
>>>>>> comprehension would be: MyType_Vec = [deepcopy(MyType_Vec[i]) for i
>>>>>> in [1,3,1]].
>>>>>>
>>>>>> (an array comprehension also answers your first question: MyType_Vec
>>>>>> = [MyType([0.0]) for i=1:3])
>>>>>>
>>>>>> On Friday, August 12, 2016 at 11:47:39 AM UTC-4, Jan wrote:
>>>>>>
>>>>>> I have a beginner question for which I cannot find the answer after
>>>>>>> quite some searching.
>>>>>>>
>>>>>>>
>>>>>>> type MyType
>>>>>>>   a::Array{Float64,1}
>>>>>>> end
>>>>>>>
>>>>>>> # Fill an array with "independent" instances of MyType. (By the
>>>>>>> way, is there a shorter way to do this?)
>>>>>>>
>>>>>>> MyType_Vec = Array(MyType, 3);
>>>>>>>
>>>>>>> for i in eachindex(MyType_Vec)
>>>>>>>
>>>>>>>   MyType_Vec[i] = MyType([0.0]);
>>>>>>>
>>>>>>> end
>>>>>>>
>>>>>>> MyType_Vec
>>>>>>>
>>>>>>> # Change the value of MyType_Vec[1].a[1] to 2.
>>>>>>>
>>>>>>> MyType_Vec[1].a[1] = 2;
>>>>>>>
>>>>>>> MyType_Vec
>>>>>>>
>>>>>>> # Shuffle the vector but with repeated elements
>>>>>>>
>>>>>>> MyType_Vec = MyType_Vec[[1,3,1]];
>>>>>>>
>>>>>>> # Change the value of MyType_Vec[1].a[1] to 4.
>>>>>>>
>>>>>>> MyType_Vec[1].a[1] = 4;
>>>>>>>
>>>>>>> MyType_Vec
>>>>>>>
>>>>>>> # The value of MyType_Vec[3].a[1] also changed to 4.
>>>>>>>
>>>>>>>
>>>>>>> How can I avoid this reference behaviour? I want that, after the
>>>>>>> shuffling step, the 3 elements of MyType_Vec should be "independent" so
>>>>>>> that if I change MyType_Vec[1].a[1] nothing else is affected. I
>>>>>>> have tried copy and deepcopy without success.
>>>>>>>
>>>>>>> I would be very happy if someone could help me out. I'm stuck...
>>>>>>>
>>>>>>> Many thanks in advance.
>>>>>>>
>>>>>> ​
>>>>>>
>>>>>
>>

Reply via email to